PySimpleGUIQt如何同时监听窗口与系统托盘的事件
PySimpleGUIQt 窗口与托盘事件响应异常修复方案
问题原因
你的代码中window.Read()是阻塞调用,程序运行到这一步会一直等待窗口产生事件,没有窗口事件时根本不会执行后续的tray.Read()逻辑,所以才会出现必须先触发窗口事件才能响应托盘操作的问题。另外GUI框架的所有界面相关操作都要求在主线程执行,用多线程分别处理窗口和托盘逻辑本身就不符合PySimpleGUI的设计规范,必然会出现异常。
修复代码
将窗口和托盘的读取都改为非阻塞模式,添加timeout参数让程序可以循环轮询两类事件即可:
import PySimpleGUIQt as Sg for_default = ['a', 'v', 's'] menu_def = ['', ['---', '&p1', ['x', 'y'], '&p2', 'E&xit']] layout = [[Sg.Text('Default First Second')], [Sg.Listbox(for_default, enable_events=True, key='-DEFAULT-'), Sg.Listbox(for_default, enable_events=True, key='-FIRST-'), Sg.Listbox(for_default, enable_events=True, key='-SECOND-')]] window = Sg.Window('Window Title', layout, finalize=True) tray = Sg.SystemTray(menu=menu_def) tray.ShowMessage('My Message', 'The tray icon is up and runnning!') while True: # 窗口读取添加timeout参数,单位为毫秒,设为非阻塞模式 event, values = window.Read(timeout=100) # 托盘读取也设为非阻塞模式 menu_item = tray.Read(timeout=0) # 处理窗口关闭事件 if event == Sg.WINDOW_CLOSED: break # 处理托盘事件 if menu_item == 'Exit': tray.close() window.close() break elif menu_item == Sg.EVENT_SYSTEM_TRAY_ICON_DOUBLE_CLICKED: window.un_hide() # 处理窗口控件事件 if event == '-DEFAULT-': print(event)
注意事项
- 非阻塞模式下的timeout数值可以根据需求调整,数值越小响应速度越快但CPU占用越高,100~200毫秒的设置就可以满足绝大多数场景的流畅响应需求
- 所有PySimpleGUI的界面相关操作都不要放到子线程执行,否则会出现不可预期的崩溃、无响应问题
内容的提问来源于stack exchange,提问作者LoNE WoLvES
相关产品推荐
相关产品推荐

