You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在指定函数内持续检测按键触发跳转,且不干扰其他按键逻辑?

问题:在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()

关键说明

  1. 线程控制:stop_event是线程间通信的安全方式,按下按键或main函数结束时,都会触发停止信号,检测线程立刻退出。
  2. 非阻塞延迟:替换time.sleep为计时循环,避免主线程阻塞时无法及时响应按键触发的界面跳转。
  3. 局部生效:检测逻辑完全封装在main函数内,离开main后stop_event会被设置,检测线程终止,不会影响其他函数的按键使用。

内容的提问来源于stack exchange,提问作者Tel e

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 16:05:41