如何将窗口关闭(红色X)链接到PyQt中关闭所有线程的函数?
我现在正在开发一个图形用户界面(GUI)应用程序,使用的是 PyQt
。
这个GUI的功能涉及到多个线程。我猜这就是为什么当我点击窗口右上角的红色“x”时,
程序并没有完全关闭(尽管界面看起来消失了)。
有没有办法把主窗口的“x”按钮和一个关闭功能连接起来,这样可以停止所有的线程?
我对 PyQt
还不太熟悉,所以请多多包涵!(另外,我相信我所有的线程都是Python线程,而不是Q线程)
1 个回答
1
你可以在启动线程之前,把Thread
对象的daemon
标志设置为True
。根据文档的说明:
一个线程可以被标记为“守护线程”。这个标记的意思是,当程序中只剩下守护线程时,整个Python程序会退出。这个标记的初始值是从创建它的线程继承来的。你可以通过
daemon
属性来设置这个标记。
值得注意的是,这样做可能会有风险,具体取决于你的后台线程在做什么(再次引用文档):
守护线程在程序关闭时会被突然停止。它们的资源(比如打开的文件、数据库事务等)可能不会被正确释放。如果你希望你的线程能够优雅地停止,就要把它们设置为非守护线程,并使用合适的信号机制,比如
Event
。
实现优雅关闭的方式有点依赖于你线程代码的具体实现,但大致会像这样:
线程方法:
def threaded_method(event, ...):
while True:
if event.is_set()
# clean up
return
# Normal stuff it does goes here.
主线程:
def on_exit(): # called when X in main window pressed
event.set() # Tell threads to cleanup.
# Do normal exit stuff.
if __name__ == "__main__":
event = threading.Event()
t = threading.Thread(target=threaded_method, args=(event, ...))
#t.daemon = True # Assuming you don't care about gracefully stopping the threads, you can just do this and leave out the Event stuff.
t.start()
# other stuff
需要注意的是,如果你的线程中的循环在某些事情上被阻塞(比如从子进程获取数据),而这些事情在程序退出时不会解除阻塞,那么这种方法可能就不奏效。如果是这种情况,请告诉我,我可以重新调整我的回答来解决这个问题。