如何创建对类中所有函数生效的Tkinter退出按钮?
解决方案
原代码无法正常退出的核心问题是:线程函数func_to_be_threaded里没有检查threading.Event的状态,即便调用了e.set(),线程还是会继续执行完循环才停止。要实现一键终止类中所有线程函数的功能,可以按以下方式改进:
改进思路
- 让类实例持有一个全局的停止信号(
threading.Event),所有线程函数共享这个信号 - 每个线程函数在循环中定期检查该信号,一旦信号被触发就终止执行
- Tkinter退出按钮只需触发这个全局信号,再等待所有线程完成后关闭窗口
完整代码示例
import threading import tkinter as tk import time def threaded(fn): def wrapper(self, *args, **kwargs): thread = threading.Thread(target=fn, args=(self, *args, **kwargs)) thread.start() return thread return wrapper class MyClass: def __init__(self): self.stop_event = threading.Event() # 全局停止信号 self.threads = [] # 存储所有线程句柄 @threaded def func_to_be_threaded(self): i = 10 while i > 1 and not self.stop_event.is_set(): print("xyz") time.sleep(2) i -= 1 print("func_to_be_threaded 已停止") @threaded def another_threaded_func(self): while not self.stop_event.is_set(): print("abc") time.sleep(1) print("another_threaded_func 已停止") def stop_all_threads(self): self.stop_event.set() # 触发全局停止信号 # 等待所有线程结束 for thread in self.threads: if thread.is_alive(): thread.join() def main(): root = tk.Tk() my_obj = MyClass() # 启动多个线程函数 my_obj.threads.append(my_obj.func_to_be_threaded()) my_obj.threads.append(my_obj.another_threaded_func()) def _quit(): print("Exiting...") my_obj.stop_all_threads() root.quit() root.destroy() QuitButton = tk.Button(master=root, text="Quit", command=_quit) QuitButton.pack(side=tk.BOTTOM) root.mainloop() if __name__ == "__main__": main()
关键改进点
- 类的
__init__方法初始化了stop_event(全局停止信号)和threads列表(统一管理所有线程) - 装饰器
threaded传递类实例self,让线程函数能访问全局停止信号 - 每个线程函数的循环条件加入
not self.stop_event.is_set(),定期检查停止信号 - 退出按钮调用
my_obj.stop_all_threads(),统一触发停止信号并等待所有线程结束
这样不管类中有多少个线程函数,只要在循环中检查全局停止信号,就能通过一个退出按钮全部终止。
内容的提问来源于stack exchange,提问作者dd24
相关产品推荐
相关产品推荐

