此子类化 QThread 与 moveToThread 示例所需的解释

explanation needed for this subclassing QThread vs moveToThread example

我正在尝试在我的 GUI 之外创建一个新的线程工作者。当我将 QThread 子类化时,它按我预期的方式工作,GUI 不受影响。当我使用 moveToThread 技术时,我完全锁定了 GUI。我假设我不小心将新线程放入主线程,但我不明白我在做什么导致的。如何在不冻结主线程的情况下让 start2 函数工作?

from PySide import QtGui, QtCore
import sys
import time

class THREAD(QtCore.QThread):
    def __init__(self):
        super(THREAD, self).__init__()

    def run(self):
        time.sleep(5)
        print "done"

class WORKER(QtCore.QObject):
    def __init__(self):
        super(WORKER, self).__init__()

    def run(self):
        time.sleep(5)
        print "done"

class GUI(QtGui.QDialog):
    def __init__(self):
        super(GUI, self).__init__()

        mainLayout = QtGui.QHBoxLayout()
        self.setLayout(mainLayout)
        start1Button = QtGui.QPushButton("Start1")
        start2Button = QtGui.QPushButton("Start2")
        mainLayout.addWidget(start1Button)
        mainLayout.addWidget(start2Button)
        start1Button.clicked.connect(self.start1)
        start2Button.clicked.connect(self.start2)

    def start1(self):
        self.myThread = THREAD()
        self.myThread.start()

    def start2(self):
        myWorker = WORKER()
        myThread = QtCore.QThread()
        myThread.start()
        myWorker.moveToThread(myThread)
        myWorker.run()

def main():
    app = QtGui.QApplication(sys.argv)
    ex = GUI()
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

首先,您需要保留您创建的工作线程和线程的引用,否则它们将在 start2() returns.

后立即被垃圾回收

其次,直接在start2()内部调用myWorker.run(),意味着会在主线程内执行。所以你必须安排在线程启动后稍后调用它。通常的方法是使用信号。

因此您的代码应如下所示:

    def start2(self):
        self.myWorker = WORKER()
        self.myThread2 = QtCore.QThread()
        self.myWorker.moveToThread(self.myThread2)
        self.myThread2.started.connect(self.myWorker.run)
        self.myThread2.start()