Search code examples
pythonpython-3.xpyqtpyqt5qrunnable

Connect QRunnable to a function/method when finished


QThread has a finished signal, and I am able to do something when thread is finished (connect to a method/function), however I would like to do this with QRunnable as well. Is there a way to connect the QRunnable thread to a method/function when it is done?

QThread:

class HelloWorldTask(QThread):
    def __init__(self):
        QThread.__init__(self)
    def run(self):
        import time
        time.sleep(3)
        print ("Running thread \n")
        time.sleep(3)

hello.finished.connect(check)

def check():
    print('Thread Done')

output:

Running thread

finished

QRunnable:

instance = QThreadPool.globalInstance()


class HelloWorldTask(QRunnable):
    def __init__(self):
        super().__init__(self)
    def run(self):
        import time
        time.sleep(3)
        print ("Running thread \n")
        time.sleep(3)

hello = HelloWorldTask()
#hello.finished.connect(check) <-- how to connect to a method/function when finished.
instance.start(hello)
print(instance.waitForDone())

def check():
    print('Thread Done')

desired output:

Running thread

Thread Done


Solution

  • QRunnable does not have a finished signal since it is not a QObject, so a possible solution is to create another class that inherits from QObject so that it emits the signal:

    from PyQt5 import QtCore
    
    
    class Signals(QtCore.QObject):
        finished = QtCore.pyqtSignal()
    
    
    class HelloWorldTask(QtCore.QRunnable):
        def __init__(self):
            super().__init__()
            self.signal = Signals()
    
        def run(self):
            import time
    
            time.sleep(3)
            print("Running thread \n")
            time.sleep(3)
            self.signal.finished.emit()
    
    
    def check():
        print("Thread Done")
        QtCore.QCoreApplication.quit()
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtCore.QCoreApplication(sys.argv)
        hello = HelloWorldTask()
        hello.signal.finished.connect(check)
        QtCore.QThreadPool.globalInstance().start(hello)
        sys.exit(app.exec_())