How to stop a QThread from the GUI

后端 未结 3 528
死守一世寂寞
死守一世寂寞 2020-12-14 23:43

This is a follow up question to a previous one I posted earlier. The problem is how to stop (terminate|quit|exit) a QThread from the GUI when using the recommended method

3条回答
  •  不思量自难忘°
    2020-12-14 23:54

    I found out that my original question was actually two questions in one: in order to stop a secondary thread from the main one, you need two things:

    1. Be able to communicate from the main thread down to the secondary thread

    2. Send the proper signal to stop the thread

    I haven't been able to solve (2), but I figured out how to solve (1), which gave me a workaround to my original problem. Instead of stopping the thread, I can stop the thread's processing (the longRunning() method)

    The problem is that a a secondary thread can only respond to signals if it runs its own event loop. A regular Qthread (which is what my code used) does not. It is easy enough, though, to subclass QThread to that effect:

    class MyThread(QThread):
        def run(self):
            self.exec_()
    

    and used self.simulThread = MyThread() in my code instead of the original self.simulThread = Qthread(). This ensures that the secondary thread runs an event loop. That was not enough, though. The longRunning() method needs to have a chance to actually process the event coming down from the main thread. With the help of this SO answer I figured out that the simple addition of a QApplication.processEvent() in the longRunning() method gave the secondary thread such a chance. I can now stop the processing carried out in the secondary thread, even though I haven't figured out how to stop the thread itself.

    To wrap up. My longRunning method now looks like this:

    def longRunning(self):
        while self._step  < self._maxSteps  and self._isRunning == True:
            self._step += 1
            self.stepIncreased.emit(self._step)
            time.sleep(0.1)
            QApplication.processEvents() 
    

    and my GUI thread has these three lines that do the job (in addition to the QThread subclass listed above):

        self.simulThread = MyThread()
        self.simulRunner.moveToThread(self.simulThread)
        self.stopButton.clicked.connect(self.simulRunner.stop)
    

    Comments are welcome!

提交回复
热议问题