如何在PySimpleGUI中点击Exit按钮终止子线程的while True循环
解决方案
核心问题原因
- 线程创建语法错误:给
threading.Thread的target参数传参时写了Config.whileLoop(),加括号等于直接在主线程同步执行死循环函数,没有实际启动子线程,主界面事件循环直接被卡住,点击Exit按钮不会触发响应。 - 循环无退出控制逻辑,且未给子线程设置守护属性,就算线程正常启动,主程序退出时死循环的子线程仍在运行,会导致进程无法正常结束。
- 原代码未导入
WIN_CLOSED常量,事件判断时会触发未定义报错。
修改后代码
Main.py
import PySimpleGUI as sg from PySimpleGUI.PySimpleGUI import WIN_CLOSED import Config import threading # 全局退出标志,用于优雅终止子线程 exit_flag = False def main(): global exit_flag layout = [ [sg.Text('Real Time Raspberry Pi Sniffer')], [sg.Button('Run While Loop'), sg.Button('Exit')], [sg.Output(size=(60,15))] ] window = sg.Window('Realtime Shell Command Output', layout) # 用于记录子线程对象,避免重复启动 loop_thread = None while True: event, values = window.Read() if event == 'Run While Loop': if not loop_thread or not loop_thread.is_alive(): # target只传函数名,不加括号,设置daemon=True为主线程守护线程 loop_thread = threading.Thread(target=Config.whileLoop, args=(lambda: exit_flag,)) loop_thread.daemon = True loop_thread.start() elif event == 'Exit' or event == WIN_CLOSED: print('CLICKED EXIT') # 先设置退出标志,通知子线程结束 exit_flag = True window.Close() break if __name__ == '__main__': main()
Config.py
def whileLoop(exit_check): # 每次循环都检查退出标志 while not exit_check(): print("It works!")
逻辑说明
- 守护线程设置:子线程设置
daemon=True后,主程序退出时会自动强制终止所有守护子线程,不会出现进程卡主的情况。 - 退出标志控制:通过传入匿名函数作为退出检查参数,子线程每次循环都会判断是否需要退出,可避免强制杀线程导致的资源泄漏问题,适合循环内有文件读写、硬件操作等需要优雅释放资源的场景。
内容的提问来源于stack exchange,提问作者BrandonB
相关产品推荐
相关产品推荐

