Python keyboard模块add_hotkey在Windows锁定后失效问题求助
问题根因
- 你使用的
keyboard库底层依赖Windows全局钩子实现热键监听,系统锁屏/解锁会触发桌面会话切换,原有钩子会被系统强制回收,导致热键失效 - 代码本身存在基础缺陷:未初始化全局
exit变量、未导入time.sleep依赖、主动绑定系统默认的Win+L锁屏热键会和系统逻辑冲突,进一步加剧线程卡死问题
解决方案
方案1:替换为兼容性更好的pynput库(推荐)
pynput对Windows会话切换的适配远好于keyboard库,不会出现解锁后卡死、热键失效的问题,完整可运行代码如下:
import sys from pynput import keyboard # 初始化退出标记 exit_flag = False def ctrl_f2(): print(" You pressed control + F2.") def ctrl_f3(): print(" You pressed control + F3.") def ctrl_f4(): print(" You pressed control + F4.") def ctrl_f12(): global exit_flag print(" You have pressed control + F12, exiting the program now.") exit_flag = True sys.exit() # 注册全局热键 with keyboard.GlobalHotKeys({ '<ctrl>+<f2>': ctrl_f2, '<ctrl>+<f3>': ctrl_f3, '<ctrl>+<f4>': ctrl_f4, '<ctrl>+<f12>': ctrl_f12}) as listener: listener.join()
使用前先安装依赖:pip install pynput,运行时建议使用管理员权限启动脚本,避免热键注册权限不足。
方案2:继续使用keyboard库的修复方法
如果必须保留原有keyboard库的实现,按以下步骤修改:
- 移除对
Win+L系统热键的绑定,避免和系统锁屏逻辑冲突 - 新增Windows会话变更事件监听,检测到解锁操作时,先调用
keyboard.unhook_all()清空原有钩子,再重新注册所有热键 - 替换原有
sleep循环为事件监听逻辑,减少线程假死概率
修改后核心代码示例:
import sys import time import keyboard import win32con import win32gui import win32ts # 初始化退出标记 exit_flag = False def ctrl_f2(): print(" You pressed control + F2.") def ctrl_f3(): print(" You pressed control + F3.") def ctrl_f4(): print(" You pressed control + F4.") def ctrl_f12(): global exit_flag print(" You have pressed control + F12, exiting the program now.") exit_flag = True sys.exit() def register_hotkeys(): keyboard.unhook_all() keyboard.add_hotkey('ctrl+F2', ctrl_f2) keyboard.add_hotkey('ctrl+F3', ctrl_f3) keyboard.add_hotkey('ctrl+F4', ctrl_f4) keyboard.add_hotkey('ctrl+F12', ctrl_f12) def wnd_proc(hwnd, msg, wparam, lparam): if msg == win32con.WM_WTSSESSION_CHANGE: # 检测到解锁事件 if wparam == win32ts.WTS_SESSION_UNLOCK: # 重新注册热键 register_hotkeys() return win32gui.DefWindowProc(hwnd, msg, wparam, lparam) if __name__ == "__main__": # 注册会话监听窗口 wc = win32gui.WNDCLASS() wc.lpfnWndProc = wnd_proc wc.lpszClassName = "HotkeySessionListener" win32gui.RegisterClass(wc) hwnd = win32gui.CreateWindow(wc.lpszClassName, "HotkeyListener", 0, 0, 0, 0, 0, 0, 0, 0, None) win32ts.WTSRegisterSessionNotification(hwnd, win32ts.NOTIFY_FOR_THIS_SESSION) # 首次注册热键 register_hotkeys() # 主线程循环 while not exit_flag: win32gui.PumpWaitingMessages() time.sleep(0.1)
该方案需要额外安装pywin32依赖:pip install pywin32
内容的提问来源于stack exchange,提问作者Aaron Jones
相关产品推荐
相关产品推荐

