PySide wait for signal from main thread in a worker thread

后端 未结 2 1869
野性不改
野性不改 2020-12-19 07:08

I decided to add a GUI to one of my scripts. The script is a simple web scraper. I decided to use a worker thread as downloading and parsing the data can take a while. I dec

相关标签:
2条回答
  • 2020-12-19 07:40

    What you are describing looks ideal for QWaitCondition.

    Simple example:

    import sys
    from PySide import QtCore, QtGui
    
    waitCondition = QtCore.QWaitCondition()
    mutex = QtCore.QMutex()
    
    class Main(QtGui.QMainWindow):
        def __init__(self, parent=None):
            super(Main, self).__init__()
    
            self.text = QtGui.QLineEdit()
            self.text.returnPressed.connect(self.wakeup)
    
            self.worker = Worker(self)
            self.worker.start()
    
            self.setCentralWidget(self.text)
    
        def wakeup(self):
            waitCondition.wakeAll()
    
    class Worker(QtCore.QThread):
        def __init__(self, parent=None):
            super(Worker, self).__init__(parent)
    
        def run(self):
            print "initial stuff"
    
            mutex.lock()
            waitCondition.wait(mutex)
            mutex.unlock()
    
            print "after returnPressed"
    
    if __name__=="__main__":      
        app = QtGui.QApplication(sys.argv)
        m = Main()
        m.show()
        sys.exit(app.exec_())
    
    0 讨论(0)
  • 2020-12-19 07:49

    The slot is executed inside the thread which created the QThread, and not in the thread that the QThread controls.

    You need to move a QObject to the thread and connect its slot to the signal, and that slot will be executed inside the thread:

    class SignalReceiver(QtCore.QObject):
        def __init__(self):
            self.eventLoop = QEventLoop(self)             
    
        @PySide.QtCore.Slot(str)
        def stop_waiting(self, text):                   
            self.text = text
            eventLoop.exit()
    
        def wait_for_input(self):
            eventLoop.exec()
            return self.text
    
    class MainWindow(...):
         ...
         def __init__(self):
            ...
            self.helper_signal.connect(self.worker.signalReceiver.stop_waiting)
    
    class WorkerThread(PySide.QtCore.QThread): 
        def __init__(self):
            self.signalReceiver = SignalReceiver() 
            # After the following call the slots will be executed in the thread             
            self.signalReceiver.moveToThread(self)    
    
        def get(self,  *args, **kwargs):
            result = requests.get(*args, **kwargs)
            while result.history:
                ...
                self.result = self.signalReceiver.wait_for_input()   
    
    0 讨论(0)
提交回复
热议问题