如何从GUI应用程序正确终止QThread?

时间:2011-10-28 10:26:40

标签: python multithreading qt pyqt

我尝试在QThread类中使用self.terminate(),在GUI类中使用self.thread.terminate()。我也尝试在两种情况下都放self.wait()。但是,有两种情况发生:

1)线程根本没有终止,GUI冻结等待线程完成。线程完成后,GUI解冻,一切恢复正常。

2)线程确实终止了,但同时冻结了整个应用程序。

我也尝试过使用self.thread.exit()。没有快乐。

为了进一步澄清,我正在尝试在GUI中实现一个用户中止按钮,它将在任何时间点终止线程的执行。

提前致谢。

编辑:

以下是run()方法:

def run(self):
    if self.create:
        print "calling create f"
        self.emit(SIGNAL("disableCreate(bool)"))
        self.create(self.password, self.email)
        self.stop()            
        self.emit(SIGNAL("finished(bool)"), self.completed)

def stop(self):
     #Tried the following, one by one (and all together too, I was desperate):
     self.terminate()
     self.quit()
     self.exit()
     self.stopped = True
     self.terminated = True
     #Neither works

这是用于中止线程的GUI类方法:

def on_abort_clicked(self):
     self.thread = threadmodule.Thread()
     #Tried the following, also one by one and altogether:
     self.thread.exit()
     self.thread.wait()
     self.thread.quit()
     self.thread.terminate()
     #Again, none work

2 个答案:

答案 0 :(得分:5)

来自QThread :: terminate的Qt文档:

  

警告:此功能很危险,不建议使用它。该   线程可以在其代码路径中的任何位置终止。线程可以   修改数据时终止。线程没有机会   自行清理,解锁任何固定的互斥锁等。简而言之,使用   只有绝对必要时才能使用此功能。

重新思考您的线程策略可能是一个更好的主意,例如你可以使用QThread :: quit()来指示线程干净地退出,而不是试图让线程以这种方式终止。实际上从线程内调用thread.exit()应该这样做,具体取决于你如何实现run()。如果你想分享你的线程运行方法的代码,可能会暗示它为什么不起作用。

答案 1 :(得分:0)

这就是我所做的:

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    stop_flag = 1
    ...

#=========500 ms class ===================
class Timer500msThread(QThread):
    signal_500ms = pyqtSignal(str) 
    ....
    def timer500msProcess(self):
        if MainWindow.stop_flag == 0 :
            self.timer_500ms.stop()
#==========
#=========Main Window ===================
        
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
MainWindow.stop_flag=0      #this sets the flag to 0 and when the next 500ms triggers the 
                               #the thread ends
print("Program Ending")