如何在指定函数内持续检测按键触发跳转,且不干扰其他按键逻辑?
问题:在main函数全程响应A/B键切换界面
需求:main函数运行期间,任何时候按下A/B键都能跳转到对应界面;检测逻辑仅在main内生效,不干扰其他代码的按键使用。原代码用_thread实现失败,需要调整方案。
原代码
import time import _thread # 假设button_a、button_b、clear、play、howToPlay、display已定义 def buttonB(): if button_b.read(): clear() play() def buttonA(): clear() howToPlay() # Creates Main Title Screens def main(): t1= _thread.start_new_thread(buttonB, ()) # Creates Game Title Screen clear() display.set_pen(GREEN) display.text("Blink of an Eye", 30, 25, 240, 5) display.update() time.sleep(2) clear() screen = 1 # Switches between two "screens" while True: # How To play Title Screen if screen == 1: display.set_pen(YELLOW) display.text('''How To Play: Press 'A' ''', 15, 35, 240, 4) display.update() time.sleep(1) clear() screen = 2 # Play Title Screen elif screen == 2: display.set_pen(MAGENTA) display.text('''Play: Press 'B' ''', 15, 35, 240, 4) display.update() time.sleep(1) clear() screen = 1
解决方案
改用threading模块(比_thread更安全、易控制),配合事件标志实现局部按键检测,具体调整如下:
核心思路
- 用
threading.Event作为停止信号,确保main函数退出时按键检测立刻终止,不干扰后续代码。 - 单独启动一个线程持续监听按键,触发后执行对应操作并停止检测。
- 把原代码中的
time.sleep替换为计时循环,避免主线程阻塞导致的响应延迟。
修改后完整代码
import time import threading # 假设button_a、button_b、clear、play、howToPlay、display、GREEN/YELLOW/MAGENTA已定义 def detect_keys(stop_event): # 持续检测按键,直到收到停止信号 while not stop_event.is_set(): if button_a.read(): stop_event.set() # 触发停止信号,终止检测 clear() howToPlay() return if button_b.read(): stop_event.set() clear() play() return time.sleep(0.01) # 降低CPU占用 def main(): # 创建停止事件,用于控制检测线程 stop_event = threading.Event() # 启动按键检测线程,设为守护线程(主线程结束时自动退出) key_thread = threading.Thread(target=detect_keys, args=(stop_event,)) key_thread.daemon = True key_thread.start() # 初始标题画面 clear() display.set_pen(GREEN) display.text("Blink of an Eye", 30, 25, 240, 5) display.update() # 计时等待2秒,期间允许按键中断 start_time = time.time() while time.time() - start_time < 2 and not stop_event.is_set(): time.sleep(0.01) if stop_event.is_set(): return # 若已触发按键,直接退出main clear() screen = 1 while not stop_event.is_set(): if screen == 1: display.set_pen(YELLOW) display.text('How To Play: Press "A"', 15, 35, 240, 4) display.update() # 计时等待1秒,期间允许按键中断 start_time = time.time() while time.time() - start_time < 1 and not stop_event.is_set(): time.sleep(0.01) if stop_event.is_set(): break clear() screen = 2 elif screen == 2: display.set_pen(MAGENTA) display.text('Play: Press "B"', 15, 35, 240, 4) display.update() start_time = time.time() while time.time() - start_time < 1 and not stop_event.is_set(): time.sleep(0.01) if stop_event.is_set(): break clear() screen = 1 # 退出main前确保停止检测 stop_event.set()
关键说明
- 线程控制:
stop_event是线程间通信的安全方式,按下按键或main函数结束时,都会触发停止信号,检测线程立刻退出。 - 非阻塞延迟:替换
time.sleep为计时循环,避免主线程阻塞时无法及时响应按键触发的界面跳转。 - 局部生效:检测逻辑完全封装在main函数内,离开main后
stop_event会被设置,检测线程终止,不会影响其他函数的按键使用。
内容的提问来源于stack exchange,提问作者Tel e
相关产品推荐
相关产品推荐

