Search code examples
python-3.xpyqt5

How to communicate QThread with my Widgets from main class


My app is freezing because i need to create a new QThread, but am a little confused how to create it when i call widgets that exists on the main class.

here is my code so far ...

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.uic import loadUi
import time

##Main Class
class HWindow(QtWidgets.QWidget):
    
    def __init__(self):
        super(HWindow, self).__init__()
        loadUi("Hw.ui",self) ##load ui

        #Create a QThread object
        self.thread = QtCore.QThread()
        #Create a QThread object
        self.workerMain = WorkerMain()
        #Move worker to the thread
        self.workerMain.moveToThread(self.thread)
        #Start the thread
        self.thread.start()
        self.runningMain = False


    def activateMain(self):
        if self.chkb_main.isChecked():
            self.lbl_disena_main.setText("Activated")
            self.lbl_disena_main.setStyleSheet('color: green;')
            #Change variable and call the function
            runningMain = True 
            self.myFunction()            
        else:
            self.lbl_disena_main.setText("Disabled")
            self.lbl_disena_main.setStyleSheet('color: red;')
            #Change variable and call the function
            runningMain = False 

    def myFunction(self):
        while self.runningMain == True:
            if self.gpb_main.isChecked() and self.chkb_main.isChecked():
                print("running ...")
                time.sleep(3)

##Worker Class
class WorkerMain(QtCore.QObject):
    threadRunning = QtCore.pyqtSignal()

    def __init__(self):
        super(WorkerMain, self).__init__()

    def run(self):
        print("Thread Running ...")

        #i cant call my widgets from my main class from here.
        '''
        while self.runningMain == True:
            if self.gpb_main.isChecked() and self.chkb_main.isChecked():
                print("running ...")
                time.sleep(3)
        '''

    def stop(self):
        print("Thread Stopped ...")
        self.terminate()
        

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    hWindow = QtWidgets.QWidget()
    hWindow = HWindow()  
    hWindow.show()
    sys.exit(app.exec_())

Based on pyqt5 documentation and examples, you create a loop on the run method, but it is complicated when i have to create that loop based on what the user select (GUI widgets).


Solution

  • i just figure it out, here is my code ...

    class HWindow(QtWidgets.QWidget):
        
        def __init__(self):
            super(HWindow, self).__init__()
            loadUi("Hw.ui",self) ##load ui
    
            #Create a QThread object
            self.thread = QtCore.QThread()
            #Create a QThread object
            self.workerMain = WorkerMain(self)
            #Move worker to the thread
            self.workerMain.moveToThread(self.thread)
            #Connect the start signal to the run slot
            self.workerMain.threadRunning.connect(self.workerMain.run)
            #Connect the activateMain signal to the start slot
            self.chkb_main.toggled.connect(self.activateMain)
            #Start the thread
            self.thread.start()
    
    
        def activateMain(self):
            if self.chkb_main.isChecked():
                self.lbl_disena_main.setText("Activated")
                self.lbl_disena_main.setStyleSheet('color: green;')
                self.workerMain.runningMain = True
                self.workerMain.threadRunning.emit()
                if not self.thread.isRunning():
                    self.thread.start()          
            else:
                self.lbl_disena_main.setText("Disabled")
                self.lbl_disena_main.setStyleSheet('color: red;')
                self.workerMain.runningMain = False
                self.workerMain.stop()
    
    
    ##Worker Class
    class WorkerMain(QtCore.QObject):
        threadRunning = QtCore.pyqtSignal()
        def __init__(self, parent):
            super(WorkerMain, self).__init__()
            self.parent = parent
            self.runningMain = False
    
        def run(self):
            print("Thread Running ...")
            while self.runningMain:
                if self.parent.gpb_main.isChecked() and self.parent.chkb_main.isChecked():
                    print("running ...")
                    time.sleep(3)
    
        def stop(self):
            print("Thread Stopped ...")
            if self.parent.thread.isRunning():
                self.parent.thread.quit()
                self.parent.thread.wait()
            
    
    if __name__ == "__main__":
        import sys
        app = QtWidgets.QApplication(sys.argv)
        hWindow = QtWidgets.QWidget()
        hWindow = HWindow()  
        hWindow.show()
        sys.exit(app.exec_())