使用keybow-python库实现树莓派按键长按检测遇问题求助
问题分析与解决方法
你的问题核心出在两个关键细节上:
- 局部变量重置:每次触发
handle_key事件时,函数内部定义的key0Down和key0Up都会被重新初始化为0,导致按键释放时完全拿不到之前按下时记录的时间值。 - 时间获取逻辑冗余且错误:外层
while循环里的now持续更新,但事件触发时的now是循环当前的时间,并非按键按下瞬间的时间;同时你把时间转成字符串再解析成小数的做法完全没必要,直接用时间戳更准确高效。
修正后的代码示例
import time import keybow # 全局变量存储按键0的按下时间戳 key0_down_time = 0.0 # 长按阈值(单位:秒,可根据需求调整) LONG_PRESS_THRESHOLD = 2.0 @keybow.on() def handle_key(index, state): global key0_down_time # 声明使用全局变量 if index == 0: if state: # 按键按下时,记录当前高精度时间戳 key0_down_time = time.time() print(f"按键0按下,时间戳:{key0_down_time}") else: # 按键释放时,计算持续时长 key0_up_time = time.time() press_duration = key0_up_time - key0_down_time print(f"按键0释放,持续时长:{press_duration:.2f}秒") if press_duration >= LONG_PRESS_THRESHOLD: print("执行关机操作!") else: print("短按,不执行关机") elif index == 3 and not state: print("Hello!") elif index == 6 and not state: print("World!") # 启动keybow内置的事件循环,无需自行编写while循环 keybow.run()
关键优化点说明
- 使用全局变量存储按键按下时间,避免每次事件触发时变量被重置
- 用
time.time()直接获取高精度时间戳,计算差值即可得到按键持续时长,无需复杂的字符串转换 - 移除了自行编写的
while True循环,因为keybow.run()已经封装了成熟的事件循环,手动循环会导致事件处理冲突或延迟
扩展支持多按键长按
如果需要给多个按键添加长按检测,可以用字典存储每个按键的按下时间:
import time import keybow key_down_times = {} # 键为按键索引,值为对应按下时间戳 LONG_PRESS_THRESHOLD = 2.0 @keybow.on() def handle_key(index, state): if state: key_down_times[index] = time.time() print(f"按键{index}按下") else: press_duration = time.time() - key_down_times.get(index, 0) print(f"按键{index}释放,时长:{press_duration:.2f}秒") if press_duration >= LONG_PRESS_THRESHOLD: if index == 0: print("执行关机操作!") elif index == 3: print("执行自定义长按操作A!") else: if index == 3: print("Hello!") elif index == 6: print("World!") keybow.run()
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

