How to stop a QThread from the GUI

后端 未结 3 533
死守一世寂寞
死守一世寂寞 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:52

    I know its long ago but i just stumbled over the same problem.

    I have been also searching for an appropriate way to do this. Finally it was easy. When exiting the application the task needs to be stopped and the thread needs to be stopped calling its quit method. See stop_thread method on bottom. And you need to wait for the thread to finish. Otherwise you will get QThread: Destroyed while thread is still running' message at exit.

    (I also changed my code to use pyside)

    import time, sys
    from PySide.QtCore  import *
    from PySide.QtGui import *
    
    class Worker(QObject):
        'Object managing the simulation'
    
        stepIncreased = Signal(int)
    
        def __init__(self):
            super(Worker, self).__init__()
            self._step = 0
            self._isRunning = True
            self._maxSteps = 20
    
        def task(self):
            if not self._isRunning:
                self._isRunning = True
                self._step = 0
    
            while self._step  < self._maxSteps  and self._isRunning == True:
                self._step += 1
                self.stepIncreased.emit(self._step)
                time.sleep(0.1)
    
            print "finished..."
    
        def stop(self):
            self._isRunning = False
    
    
    class SimulationUi(QDialog):
        def __init__(self):
            super(SimulationUi, self).__init__()
    
            self.btnStart = QPushButton('Start')
            self.btnStop = QPushButton('Stop')
            self.currentStep = QSpinBox()
    
            self.layout = QHBoxLayout()
            self.layout.addWidget(self.btnStart)
            self.layout.addWidget(self.btnStop)
            self.layout.addWidget(self.currentStep)
            self.setLayout(self.layout)
    
            self.thread = QThread()
            self.thread.start()
    
            self.worker = Worker()
            self.worker.moveToThread(self.thread)
            self.worker.stepIncreased.connect(self.currentStep.setValue)
    
            self.btnStop.clicked.connect(lambda: self.worker.stop())
            self.btnStart.clicked.connect(self.worker.task)
    
            self.finished.connect(self.stop_thread)
    
        def stop_thread(self):
            self.worker.stop()
            self.thread.quit()
            self.thread.wait()
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        simul = SimulationUi()
        simul.show()
        sys.exit(app.exec_())
    

提交回复
热议问题