How to can I add threading to PyQt5 GUI?

10,982

You have forgot to connect the thread to the worker object.

self.work = Worker()
self.thread = QThread()
self.thread.started.connect(self.worker.work) # <--new line, make sure work starts.
self.thread.start()

Good luck with the application :-)

Share:
10,982
RknRobin
Author by

RknRobin

I work with rapid prototyping machinery, which lead me to python. I like to build scale-able solutions to immediate problems involved with startups or new inventions.

Updated on June 25, 2022

Comments

  • RknRobin
    RknRobin almost 2 years

    So I have created a GUI using QT Designer. It works pretty well, but on more complex calls it doesn't update the main window and locks up. I want to run my CustomComplexFunction() while updating a textEdit in the main window from constantly changing backend information, and I wanted it to run every 2 seconds. The following code seems right and runs without errors, but doesn't update the textEdit. Please note i'm importing a .ui file designed from QT Designer with a pushButton and textEdit and the code won't run without it.

    Main.py

    import sys
    from PyQt5.QtWidgets import QDialog, QApplication, QPushButton, QVBoxLayout, QMainWindow
    from PyQt5.QtCore import QCoreApplication, QObject, QRunnable, QThread, QThreadPool, pyqtSignal, pyqtSlot
    from PyQt5 import uic, QtGui
    
    class Worker(QObject):
        newParams = pyqtSignal()
    
        @pyqtSlot()
        def paramUp(self):
            x=1
            for x in range(100):
                time.sleep(2)
                self.newParams.emit()
                print ("sent new params")
                x +=1
    
    Ui_somewindow, _ = uic.loadUiType("mainwindow.ui") #the path to UI
    
    class SomeWindow(QMainWindow, Ui_somewindow, QDialog):
    
        def __init__(self):
    
            QMainWindow.__init__(self)
            Ui_somewindow.__init__(self)
            self.setupUi(self)
    
            # Start custom functions
            self.params = {}
            self.pushButton.clicked.connect(self.complex) #NumEvent
    
        def complex(self):
            self.work = Worker() 
            self.thread = QThread()
    
            self.work.newParams.connect(self.changeTextEdit)
            self.work.moveToThread(self.thread)
            self.thread.start()
    
            self.CustomComplexFunction()
    
        def CustomComplexFunction(self):
            self.params['City'] = 'Test'
    
        def changeTextEdit(self):
    
            try: 
                City = self.params['City']
                self.textEdit_14.setPlainText(City) 
            except KeyError:
                City = None
    if __name__ == "__main__":
    
        app = QApplication(sys.argv)
        window = SomeWindow()
        window.show()
        sys.exit(app.exec_())
    

    You can see the official docs for Signals and Slots here and this SO post was also very helpful, but it seems like I built it correctly. According to the docs, the emitter doesn't care if the signal is used. This might be why the code doesn't have errors but doesn't work either.

    Any ideas on how to make it work? Or atleast some way to test the emitter and signals??