RknRobin
RknRobin

Reputation: 401

How to can I add threading to PyQt5 GUI?

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??

Upvotes: 4

Views: 11657

Answers (1)

Ole
Ole

Reputation: 106

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

Upvotes: 4

Related Questions