这个子类化QThread vs moveToThread示例需要解释

时间:2016-07-10 10:53:41

标签: python pyside qthread

我正在尝试在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()

1 个答案:

答案 0 :(得分:0)

首先,您需要保留对您创建的工作线程和线程的引用,否则只要start2()返回就会收集垃圾。

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

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

    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()