如何通过自定义热键立即中断while循环?
如何通过自定义热键立即中断while循环?
嘿,我完全懂你遇到的麻烦!你现在的问题核心就是那个inputs.get_gamepad()函数——它是个阻塞式调用,会一直卡着等控制器有输入才会往下走。哪怕你按了q键触发了停止信号,程序也得等控制器动一下,才能回到循环开头检查recording变量,自然没法立刻停下来。
下面给你两个实用的解决方案,都能解决这个“卡滞”问题:
方案一:给控制器输入加超时,让循环定期检查停止信号
我们可以避开全局的inputs.get_gamepad(),直接获取游戏控制器设备,然后用带超时的读取方法。这样程序不会一直死等控制器输入,每隔一小段时间就会回到循环开头,看看是不是该停止了。
修改后的代码如下:
import inputs import keyboard recording = True def interrupt_record(): global recording recording = False print("Recording stopped!") def record(): ''' Start and stop the input recording with the "q" key Records controller inputs when they are pressed and depressed and at what time. ''' print('To start recording, press "q". Press it again to stop') # 先等第一次按q启动录制 keyboard.wait('q') global recording recording = True print("Recording started...") # 获取第一个游戏控制器设备 try: gamepad = inputs.devices.gamepads[0] except IndexError: print("没找到游戏控制器!") return while recording: try: # 读取控制器事件,超时0.1秒(可根据需求调整) events = gamepad.read(timeout=0.1) for event in events: print(event.code) except inputs.UnpluggedError: print("控制器断开连接了!") break keyboard.add_hotkey('q', interrupt_record) record()
这里的关键是gamepad.read(timeout=0.1),它最多只会等0.1秒就返回,不管有没有控制器输入。这样循环就能定期检查recording状态,你按q键后,下一次循环就会立刻终止。
方案二:用线程分离控制器输入和按键监听
把读取控制器输入的逻辑放到一个独立的子线程里,主线程专门负责监听按键和控制循环状态。这样两边互不干扰,主线程不会被控制器输入卡住,能立刻响应你的q键操作。
代码示例:
import inputs import keyboard import threading import time recording = True def read_controller(): while recording: try: events = inputs.get_gamepad() for event in events: print(event.code) except inputs.UnpluggedError: print("控制器断开连接了!") break # 加个小延迟,避免占用过多CPU资源 time.sleep(0.01) def interrupt_record(): global recording recording = False print("Recording stopped!") def record(): print('To start recording, press "q". Press it again to stop') keyboard.wait('q') global recording recording = True print("Recording started...") # 启动控制器读取的子线程(daemon=True表示主线程结束时子线程也会跟着结束) controller_thread = threading.Thread(target=read_controller, daemon=True) controller_thread.start() # 主线程只需定期检查停止信号 while recording: time.sleep(0.1) keyboard.add_hotkey('q', interrupt_record) record()
这个方案里,子线程负责盯着控制器输入,主线程只需要每隔0.1秒检查一次recording状态。你按q键时,停止信号能立刻生效,子线程会在下一次循环时自动终止。
两种方案都能解决你的问题,选哪种看你的需求:第一种更轻量,第二种适合后续要扩展更多功能的场景。另外提醒一下,Windows下使用keyboard库可能需要管理员权限才能正常监听全局热键哦。
备注:内容来源于stack exchange,提问作者RandomRepeater
相关产品推荐
相关产品推荐

