Python实现W/S/A/D/空格键精准长按时长监控的问题
多按键长按时长精准监控解决方案
问题分析
现有代码通过keyboard.read_event()阻塞读取事件,当多键同时按下时,会错过部分按键的down/up事件,导致时长统计错误。比如先按住w再按d,代码会卡在等待w的up事件,无法及时记录d的按下时间,最终统计的时长完全偏离实际。
解决方案思路
- 用字典记录每个目标按键的按下时间戳,按键触发down事件时记录时间,up事件时计算时长
- 通过事件回调监听所有按键操作,避免阻塞导致的事件丢失
- 额外维护按键按下顺序的列表,确保最终输出符合按键按下的先后顺序
- 仅统计时长超过1秒的按键操作
修改后的代码
import time import keyboard # 存储按键按下时间戳:键为按键名,值为按下时间 key_press_start = {} # 记录按键首次按下的顺序 press_order = [] # 存储符合条件的长按结果:(按键名, 时长) long_press_results = [] # 目标监控按键集合 TARGET_KEYS = {'w', 's', 'a', 'd', 'space'} def on_key_event(event): if event.name == 'esc': keyboard.unhook_all() return if event.name not in TARGET_KEYS: return if event.event_type == 'down': # 仅在按键未被记录时存储时间和顺序 if event.name not in key_press_start: key_press_start[event.name] = time.perf_counter() if event.name not in press_order: press_order.append(event.name) elif event.event_type == 'up': if event.name in key_press_start: start_time = key_press_start.pop(event.name) duration = time.perf_counter() - start_time # 筛选时长超过1秒的操作 if duration > 1: long_press_results.append((event.name, duration)) # 注册全局按键事件回调 keyboard.hook(on_key_event) # 保持程序运行,直到按下esc退出 keyboard.wait('esc') # 按按键按下顺序输出结果 print("\n按按键按下顺序输出符合条件的长按时长:") output_seen = set() for key in press_order: for res in long_press_results: if res[0] == key and res[0] not in output_seen: print(f'- *{key}*: {res[1]:.2f} seconds') output_seen.add(key) break
代码说明
keyboard.hook()注册回调函数,能实时捕获所有按键的down/up事件,避免阻塞导致的事件丢失key_press_start确保每个按键仅记录一次按下时间,防止重复触发down事件时的错误记录press_order维护按键首次按下的顺序,保证最终输出符合用户期望的先后逻辑- 退出时按顺序整理输出结果,同时避免同一按键多次按下的重复输出
内容的提问来源于stack exchange,提问作者Crazyfrog
相关产品推荐
相关产品推荐

