如何使用keyboard.add_hotkey停止由热键启动的循环?
问题:通过热键启动的循环无法用ESC停止的解决办法
现象说明
以下代码可正常运行,按下ESC键即可停止循环:
import time import keyboard run = 1 def end(): global run run = 0 print(run) def do_stuff(): while run: print('running') time.sleep(0.5) keyboard.add_hotkey('esc', end) do_stuff()
但如果通过另一个热键(Enter)启动循环,ESC键就无法再停止它了:
import time import keyboard run = 1 def end(): global run run = 0 print(run) def do_stuff(): while run: print('running') time.sleep(0.5) keyboard.add_hotkey('esc', end) # do_stuff() keyboard.add_hotkey('enter', do_stuff) keyboard.wait()
曾尝试将while run:替换为while not keyboard.is_pressed('esc'):,虽然长按ESC键能停止循环,但这并非理想解决方案。
解决方法
使用线程将循环放到子线程中运行,避免阻塞主线程的热键监听逻辑,修改后的可正常运行代码如下:
import keyboard import threading run = 1 def end(): global run run = 0 print(run) def do_stuff(): while run: print('running') time.sleep(0.5) def new_do_stuff(): t = threading.Thread(target=do_stuff, name='LoopThread') t.start() keyboard.add_hotkey('esc', end) keyboard.add_hotkey('enter', new_do_stuff) keyboard.wait('esc')
原理说明
原代码中,通过Enter热键启动do_stuff时,while循环会占据主线程,导致keyboard库无法处理ESC热键的触发事件。把循环逻辑放到子线程后,主线程可继续监听键盘事件,ESC热键触发的end函数能正常修改全局变量run,从而终止子线程中的循环。
内容的提问来源于stack exchange,提问作者zhlzhl zhl
相关产品推荐
相关产品推荐

