You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 11:45:08