Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何从GUI应用程序正确终止QThread?_Python_Multithreading_Qt_Pyqt - Fatal编程技术网

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

Python 如何从GUI应用程序正确终止QThread?,python,multithreading,qt,pyqt,Python,Multithreading,Qt,Pyqt,我尝试在QThread类中使用self.terminate(),在GUI类中也使用self.thread.terminate()。我还尝试在这两种情况下放置self.wait()。但是,有两种情况会发生: 1) 线程根本不会终止,GUI会冻结,等待线程完成。一旦线程完成,GUI就会解冻,一切都恢复正常 2) 线程确实会终止,但同时会冻结整个应用程序 我还尝试使用self.thread.exit()。没有快乐 为了进一步澄清,我试图在GUI中实现一个用户中止按钮,该按钮将在任何时间点终止线程的执行

我尝试在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

从QThread::terminate的Qt文档中:

警告:此功能很危险,不鼓励使用。这个 线程可以在其代码路径中的任意点终止。线程可以是 在修改数据时终止。这根线没有机会断开 清理后,自己,解锁任何持有的互斥等简而言之,使用 此功能仅在绝对必要时使用

重新考虑线程策略可能是一个更好的主意,例如,您可以使用QThread::quit()发出明确退出线程的信号,而不是试图让线程以这种方式终止。实际上,从线程中调用thread.exit()应该可以做到这一点,具体取决于您如何实现run()。如果您想共享线程运行方法的代码,该代码可能会提示线程运行方法不起作用的原因。

我就是这么做的:

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")


注意:self.terminate==(self.terminated=true),仅此而已。对于99%的实现。谢谢,但这并不能真正帮助解决问题。只有一种方法可以安全终止线程-让它完成所有it任务。要执行它,您必须在执行硬任务之前检查thread.terminated。嗯,这当然不是我想要的。我假设
self.create()
方法是线程中最耗时的方法?通常情况下,您会在其中执行类似于
而不是self.terminated(){do slow operation parts..}
的操作。不幸的是,我对Python不太了解,但似乎有一个线程教程可以帮助我,我也尝试过。它碰巧起了一些作用(GUI不会冻结,但线程也不会终止)。然而,最奇怪的事情发生了。我删除了线程中的所有
def stop(self)
代码,并在GUI中单击了
def on_abort(self)
代码,然后重写了它。我只是将
self.terminate()
放在线程的
stop()
函数中,并在GUI类中执行了
self.thread.stop()
。它就像一个符咒。好了,这是我第一次尝试,但之前没有成功。我可能错过了什么。