Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QThread, moveToThread and Thread ID



  • Dear all,

    I am new to PyQt but I developed GUI apps in my past. I want to make a GUI in which a part is refreshed by a Thread. I tried to understand in the internet how it works and I made the following code (see below).

    What I do :

    • I create a "worker" class that inherits from QObject. From this worker class I print the threadID (QThread.currentThreadId())
    • this worker is instanciated in the window object. It is run through a QThread after a moveToThread operation from the window.
    • The worker sends signals to the window while it loops. The signal itself prints its threadID too
    • I added a timer to the window to display again the threadID in which the window runs.

    I obtain the same threadID in all the cases and I doubt my worker or my threadID display works well. Can you help ?

    Here comes the code, and then the results.

    Best Regards,
    Mike

    Code

    #!/opt/miniconda3/bin/python3.7
    
    from PyQt5.QtCore import QObject, QThread, pyqtSignal,QTimer
    from PyQt5.QtWidgets import QApplication,QMainWindow
    from time import sleep
    import sys
    
    class Worker(QObject):
        finished = pyqtSignal()
        progress = pyqtSignal()
    
        def run(self):
            """Long-running task."""
            while True:
                sleep(0.5)
                print("in Worker Thread : ", QThread.currentThreadId())
                self.progress.emit()
            self.finished.emit()
    
    class Window(QMainWindow):
        def __init__(self,*args,**kwargs):
            super().__init__(*args,**kwargs)
            self.runLongTask()
    
        def workerProgress(self):
            print("Report Thread : ",QThread.currentThreadId())
            print("\n")
    
    
        def mainAppProgress(self):
            print("Timer Thread : ",QThread.currentThreadId())
    
        def runLongTask(self):
            # run the worker using a thread
            self.thread = QThread()
            self.worker = Worker()
            self.worker.moveToThread(self.thread)
            self.thread.started.connect(self.worker.run)
            self.worker.progress.connect(self.workerProgress)
            self.thread.start()
    
            # run a timer to display the window thread too
            self.timer = QTimer()
            self.timer.setInterval(500)
            self.timer.timeout.connect(self.mainAppProgress)
            self.timer.start()
    
    app = QApplication(sys.argv)
    win = Window()
    win.show()
    sys.exit(app.exec())
    

    Results

    Timer Thread :  <sip.voidptr object at 0x10079f0f0>
    in Worker Thread :  <sip.voidptr object at 0x10079f0f0>
    Report Thread :  <sip.voidptr object at 0x10079f0f0>
    
    
    Timer Thread :  <sip.voidptr object at 0x10079f0f0>
    in Worker Thread :  <sip.voidptr object at 0x10079f0f0>
    Report Thread :  <sip.voidptr object at 0x10079f0f0>
    
    
    Timer Thread :  <sip.voidptr object at 0x10079f0f0>
    in Worker Thread :  <sip.voidptr object at 0x10079f0f0>
    Report Thread :  <sip.voidptr object at 0x10079f0f0>
    
    
    Timer Thread :  <sip.voidptr object at 0x10079f0f0>
    in Worker Thread :  <sip.voidptr object at 0x10079f0f0>
    Report Thread :  <sip.voidptr object at 0x10079f0f0>
    
    
    Timer Thread :  <sip.voidptr object at 0x10079f0f0>
    in Worker Thread :  <sip.voidptr object at 0x10079f0f0>
    Report Thread :  <sip.voidptr object at 0x10079f0f0>
    
    
    Timer Thread :  <sip.voidptr object at 0x10079f0f0>
    in Worker Thread :  <sip.voidptr object at 0x10079f0f0>
    Report Thread :  <sip.voidptr object at 0x10079f120>
    


  • @Mika-L What you are printing is the python object, if you want to get the id of the thread then use int():

    int(QThread.currentThreadId())
    

    Output:

    in Worker Thread :  140448685921856
    Report Thread :  140448915945280
    
    
    Timer Thread :  140448915945280
    in Worker Thread :  140448685921856
    Report Thread :  140448915945280
    
    
    Timer Thread :  140448915945280
    in Worker Thread :  140448685921856
    Report Thread :  140448915945280
    

    If you want to check if the function is executed in the main thread then compare the QThread.currentThread() with QCoreApplication.instance().thread():

    print("is executed main thread?",  QThread.currentThread() is QCoreApplication.instance().thread())
    

    Another alternative is to use the threading.current_thread() function:

    Timer Thread :  <_MainThread(MainThread, started 140013290776384)>
    in Worker Thread :  <_DummyThread(Dummy-1, started daemon 140013060752960)>
    Report Thread :  <_MainThread(MainThread, started 140013290776384)>
    
    
    Timer Thread :  <_MainThread(MainThread, started 140013290776384)>
    in Worker Thread :  <_DummyThread(Dummy-1, started daemon 140013060752960)>
    Report Thread :  <_MainThread(MainThread, started 140013290776384)>
    


  • @eyllanesc : very very nice answer ! thanks a lot ! That really helps !

    I have a last question : is there somewhere a tool to display the CPU consumption for a given thread, cross-platform ? Or a pythonic tool ?

    Thanks again,
    Mike


Log in to reply