Python 即使删除了Thread对象,QThread仍作为虚拟线程运行

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

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 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线程对象。这看起来不是你自己造成的问题。