Python脚本启动时如何非阻塞检测Ctrl等指定按键是否被按下?
方案1:使用ctypes调用系统原生API(无额外依赖、完全非阻塞)
该方案直接调用操作系统自带的按键状态查询接口,无需特殊权限,调用后立刻返回结果,稳定性最高。
Windows 实现
import ctypes # VK_CONTROL虚拟键码为0x11 def is_ctrl_pressed(): return ctypes.windll.user32.GetKeyState(0x11) & 0x8000 != 0 if __name__ == "__main__": if is_ctrl_pressed(): print("Ctrl键已按下,执行自定义逻辑") else: print("Ctrl键未按下,执行常规逻辑")
返回值的0x8000位为1就代表按键当前处于按下状态。
Linux 实现(X11桌面环境通用)
from ctypes import CDLL, c_char, c_void_p, byref X11 = CDLL("libX11.so.6") X11.XOpenDisplay.restype = c_void_p X11.XQueryKeymap.argtypes = [c_void_p, c_char * 32] def is_ctrl_pressed(): display = X11.XOpenDisplay(None) if not display: return False keys = (c_char * 32)() X11.XQueryKeymap(display, keys) X11.XCloseDisplay(display) # 左Ctrl键码37、右Ctrl键码105,任意一个按下就返回True return (keys[37 // 8] & (1 << (37 % 8))) or (keys[105 // 8] & (1 << (105 % 8)))
macOS 实现
from Quartz import CGEventSourceKeyState, kCGEventSourceStateHIDSystemState def is_ctrl_pressed(): # 左Ctrl键值为0x3B,右Ctrl为0x3E,按需修改即可 return CGEventSourceKeyState(kCGEventSourceStateHIDSystemState, 0x3B)
方案2:使用pynput模块(跨平台统一接口)
如果需要一套代码适配全平台,可以用pynput模块,状态检测比keyboard模块更稳定,不需要管理员/root权限:
- 先安装依赖:
pip install pynput - 代码示例:
from pynput.keyboard import Key, Controller keyboard = Controller() if Key.ctrl_l in keyboard.pressed_keys or Key.ctrl_r in keyboard.pressed_keys: print("Ctrl键已按下") else: print("Ctrl键未按下")
之前keyboard模块失效的原因
keyboard模块需要全局按键读取权限,Windows下没有用管理员身份运行脚本、Linux下没有加sudo执行的话,is_pressed就会一直返回False,不适合用来做启动阶段的按键检测。
内容的提问来源于stack exchange,提问作者Jorge Luis
相关产品推荐
相关产品推荐

