Python树莓派开发如何实现按键长按持续触发对应功能?
pynput仅绑定on_press事件时,系统自带的按键重复机制会在按住按键时持续触发press回调,再加上你把带固定时长的电机动作直接写在press回调里,自然会出现重复触发、松开不及时停的问题。正确实现逻辑是状态驱动而非事件驱动:不要在按键事件回调里直接执行长时间的电机动作,只在回调里更新按键状态,单独开控制循环根据实时状态持续控制电机。
核心实现逻辑
- 用字典记录所有受控方向键的实时按下/松开状态
- 分别绑定
on_press和on_release两个回调,回调里仅做状态更新,不执行任何电机动作 - 主循环高频轮询按键状态,只要对应按键处于按下状态就持续输出电机驱动信号,无按键按下立刻触发停转
修改后可直接适配的代码
from pynput.keyboard import Key, Listener import time # 初始化按键状态字典,默认所有方向键为未按下状态 key_state = { Key.up: False, Key.down: False, Key.left: False, Key.right: False } program_running = True def on_press(key): global program_running # 按delete键退出程序 if key == Key.delete: program_running = False return False # 仅更新受控按键的状态,重复触发的press事件不会改变已有状态 if key in key_state: key_state[key] = True def on_release(key): # 松开按键时立刻把对应状态标记为未按下 if key in key_state: key_state[key] = False # 启动键盘监听(监听逻辑跑在独立子线程,不阻塞主控制循环) listener = Listener(on_press=on_press, on_release=on_release) listener.start() try: while program_running: # 每轮循环先默认执行电机停转逻辑,替换成你自己的停转函数即可 # motor_stop() if key_state[Key.up]: print("forward") # 替换成你的前进驱动函数,注意不要在函数内加sleep阻塞 # forward() elif key_state[Key.down]: print("reverse") # 替换成你的后退驱动函数 # reverse() elif key_state[Key.left]: print("left") # 替换成你的左转驱动函数 # left_turn() elif key_state[Key.right]: print("right") # 替换成你的右转驱动函数 # right_turn() # 控制轮询频率,10ms间隔足够跟手,松开停转延迟人眼完全感知不到 time.sleep(0.01) finally: # 退出兜底:无论程序怎么终止,都先停电机、释放监听,避免电机失控 # motor_stop() listener.stop() listener.join()
适配注意事项
- 你原来写的
forward(0.1)、left_turn(0.1)这类带固定运行时长的函数是阻塞式的,需要先修改为非阻塞版本:函数仅负责设置电机引脚电平/PWM输出,不要在函数内部加sleep延时,否则会导致控制卡顿延迟 - 代码默认同一时间只响应一个方向键,如果需要支持组合按键(比如同时按前进+右转实现斜向行驶),把主循环里的
elif全部改成独立的if判断即可 - 10ms的轮询间隔可以根据实际需求调整,间隔越短响应越快,一般10-20ms的间隔就能满足绝大多数遥控场景的跟手性要求
内容的提问来源于stack exchange,提问作者0lof
相关产品推荐
相关产品推荐

