Python 即使删除了Thread对象,QThread仍作为虚拟线程运行
QThread似乎总是在后台运行,即使删除了Thread对象。我花了很多时间来证明我面临的问题。线程一直处于活动状态[运行、完成和删除时] 请参阅下面的代码Python 即使删除了Thread对象,QThread仍作为虚拟线程运行,python,pyqt,qthread,Python,Pyqt,Qthread,QThread似乎总是在后台运行,即使删除了Thread对象。我花了很多时间来证明我面临的问题。线程一直处于活动状态[运行、完成和删除时] 请参阅下面的代码 from PyQt4.QtCore import QThread, QTimer,QObject, pyqtSignal, pyqtSlot, Qt from PyQt4.QtGui import QApplication, QLabel, QWidget, QGridLayout import sys import time import
from PyQt4.QtCore import QThread, QTimer,QObject, pyqtSignal, pyqtSlot, Qt
from PyQt4.QtGui import QApplication, QLabel, QWidget, QGridLayout
import sys
import time
import threading
import sip
def activeThreads():
currentThread = threading.current_thread()
print("Current Thread=",currentThread)
n = 0
for td in threading.enumerate():
if td is not currentThread:
print("Thread = ",td)
class Worker(QObject):
finished = pyqtSignal()
intReady = pyqtSignal(int)
def __init__(self, maxCount):
super().__init__()
self.maxCount=maxCount
@pyqtSlot()
def procCounter(self): # A slot takes no params
for i in range(1, self.maxCount):
time.sleep(0.5)
self.intReady.emit(i)
print("Called from worker thread")
activeThreads()
self.finished.emit()
class Form(QWidget):
def __init__(self):
super().__init__()
self.label = QLabel("0")
# 1 - create Worker and Thread inside the Form
self.obj = Worker(6) # no parent!
self.thread = QThread() # no parent!
# 2 - Connect Worker`s Signals to Form method slots to post data.
self.obj.intReady.connect(self.onIntReady)
# 3 - Move the Worker object to the Thread object
self.obj.moveToThread(self.thread)
# 4 - Connect Worker Signals to the Thread slots
#self.obj.finished.connect(self.thread.quit)
self.obj.finished.connect(self.quitThread)
# 5 - Connect Thread started signal to Worker operational slot method
self.thread.started.connect(self.obj.procCounter)
# 6 - Start the thread
self.thread.start()
# 7 - Start the form
self.initUI()
def quitThread(self):
self.thread.quit()
#self.obj.deleteLater()
self.checkThread()
def checkThread(self):
try:
self.thread.objectName()
except RuntimeError as err:
print("-----------------------------------------------------------")
print("Error=",err)
print("After Worker thread object deleted")
activeThreads()
return
if self.thread.isRunning():
#print("Still running")
QTimer.singleShot(1, self.checkThread)
#activeThreads()
if self.thread.isFinished():
print("-----------------------------------------------------------")
print("After worker thread finished")
activeThreads()
self.obj.deleteLater()
self.thread.deleteLater()
QTimer.singleShot(1, self.checkThread)
def initUI(self):
grid = QGridLayout()
self.setLayout(grid)
grid.addWidget(self.label,0,0)
self.move(300, 150)
self.setWindowTitle('thread test')
self.show()
def onIntReady(self, i):
self.label.setText("{}".format(i))
app = QApplication(sys.argv)
form = Form()
sys.exit(app.exec_())
这是输出
Called from worker thread
Current Thread= <_DummyThread(Dummy-1,started daemon 6692)
Thread = <_MainThread(MainThread, started 10204)
-----------------------------------------------------------
After worker thread finished
Current Thread= <_MainThread(MainThread,started 10204)>
Thread = <_DummyThread(Dummy-1, started daemon 6692)>
-----------------------------------------------------------
Error= wrapped C/C++ object of type QThread has been deleted
After Worker thread object deleted
Current Thread= <_MainThread(MainThread, started 10204)
Thread = <_DummyThread(Dummy-1, started daemon 6692)>
从工作线程调用
当前线程=调用activeThread()
总是为我引发一个AssertionError
。可能在某个地方存在一些模糊的特定于系统的垃圾收集问题。不要将QThread
和threading
混在一起-坚持其中一种。是@ekhuro。在UI中执行操作时,我总是坚持使用QThread。然而,当用户退出我们内置于Python中的应用程序时,我们会检查活动的Python和PyQt线程,并在应用程序退出时终止它们。我希望有问题。您可以尝试在不同的环境中运行吗?但显然,工作线程确实会终止(即,它会发出finished
信号)。此外,基础C++对象已经被成功删除。如果没有使用threading
模块,就永远不会创建这些伪python线程对象。这看起来不是你自己造成的问题。