PySimpleGUI导致pynput全局热键异常 如何将二者正常结合使用
根因分析
你遇到的异常本质是PySimpleGUI弹窗运行时,其内部事件循环会抢占键盘事件回调,导致pynput的GlobalHotKeys监听器没有接收到<alt>、<ctrl>修饰键的释放信号,监听器内部会一直判定这两个修饰键处于按下状态,后续只要按下t键就会匹配到热键规则,错误触发弹窗。
修复方案
有两种常用的修复方式,都可以稳定解决该问题:
方案1:重置监听器状态
修改逻辑为触发弹窗时先停止监听器清空状态,弹窗关闭后再重启监听器,改造成本极低:
import PySimpleGUI as sg from pynput import keyboard hotkey_listener = None def f_test(): # 停止监听器清空内部按键缓存 hotkey_listener.stop() layout = [[sg.Text("Hello from PySimpleGUI")], [sg.Button("OK")]] window = sg.Window("Demo", layout) while True: event, values = window.read() if event == "OK" or event == sg.WIN_CLOSED: break window.close() # 重启监听器恢复热键功能 global hotkey_listener hotkey_listener = keyboard.GlobalHotKeys({ '<alt>+<ctrl>+t': f_test}) hotkey_listener.start() if __name__ == "__main__": hotkey_listener = keyboard.GlobalHotKeys({ '<alt>+<ctrl>+t': f_test}) hotkey_listener.start() hotkey_listener.join()
方案2:自定义热键判定逻辑
不使用pynput封装好的GlobalHotKeys,自己手动维护按键状态实时判定热键,避免内置缓存的问题,自定义程度更高:
import PySimpleGUI as sg from pynput import keyboard # 实时维护已按下的按键集合 pressed_keys = set() def on_press(key): try: pressed_keys.add(key) # 实时校验热键组合 if (keyboard.Key.alt in pressed_keys and keyboard.Key.ctrl in pressed_keys and hasattr(key, 'char') and key.char == 't'): f_test() except AttributeError: pass def on_release(key): # 释放时移除按键状态 if key in pressed_keys: pressed_keys.remove(key) # 可选:按esc退出监听 if key == keyboard.Key.esc: return False def f_test(): layout = [[sg.Text("Hello from PySimpleGUI")], [sg.Button("OK")]] window = sg.Window("Demo", layout) while True: event, values = window.read() if event == "OK" or event == sg.WIN_CLOSED: break window.close() if __name__ == "__main__": with keyboard.Listener(on_press=on_press, on_release=on_release) as listener: listener.join()
内容的提问来源于stack exchange,提问作者Sjakbajsen
相关产品推荐
相关产品推荐

