简体   繁体   English

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

[英]explanation needed for this subclassing QThread vs moveToThread example

I am trying to create a new thread worker outside of my GUI. 我正在尝试在GUI之外创建一个新的线程工作者。 When I subclass QThread it works as I expect, the GUI is unaffected. 当我将QThread子类化时,它按预期工作,GUI不受影响。 When I use the moveToThread technique, I get full lock up of the GUI. 当我使用moveToThread技术时,我完全锁定了GUI。 I assume I'm accidentally putting the new thread into the main thread, but I don't understand what I'm doing to cause that. 我假设我不小心将新线程放入主线程,但我不明白我正在做什么导致这一点。 How can have the start2 function work without freezing the main thread? 如何在不冻结主线程的情况下使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()

Firstly, you need to keep a reference the worker and thread you have created, otherwise they will get garbage-collected as soon as start2() returns. 首先,您需要保留引用您创建的worker和thread,否则只要start2()返回它们就会被垃圾收集。

Secondly, calling myWorker.run() directly inside start2() means it will be executed within the main thread. 其次,直接在start2()内调用myWorker.run()意味着它将在主线程中执行。 So you must arrange to have it called later, after the thread has started. 因此,您必须安排在线程启动后稍后调用它。 The usual way to do this is by using a signal. 通常的方法是使用信号。

Your code should therefore look something like this: 因此,您的代码应如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM