2016-07-10 12 views
1

Ich versuche, einen neuen Thread-Worker außerhalb meiner GUI zu erstellen. Wenn ich QThread unterlasse, funktioniert es wie erwartet, die GUI ist davon nicht betroffen. Wenn ich die moveToThread-Technik verwende, bekomme ich die GUI vollständig gesperrt. Ich nehme an, dass ich den neuen Thread versehentlich in den Hauptthread lege, aber ich verstehe nicht, was ich mache, um das zu verursachen. Wie kann die start2-Funktion funktionieren, ohne den Haupt-Thread einzufrieren?Erklärung für diese Unterklasse erforderlich QThread vs moveToThread Beispiel

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

Antwort

0

Zunächst müssen Sie den Arbeiter einen Verweis auf halten und fädeln Sie erstellt haben, sonst werden sie Garbage Collection, sobald start2() Renditen.

Zweitens Aufruf myWorker.run() direkt innerhalb start2() bedeutet, dass es innerhalb des Hauptthreads ausgeführt wird. Sie müssen also veranlassen, dass es später aufgerufen wird, nachdem der Thread gestartet wurde. Der übliche Weg ist ein Signal.

Der Code sollte daher wie folgt aussehen:

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

Ausgezeichnet, danke ekhumoro! – bneall