为何无法第四次按下ESC键?Python鼠标坐标捕获脚本问题排查
问题原因及解决方案
错误原因
代码中键盘监听器的on_press回调函数内使用了阻塞式的raw_input()操作。pynput的键盘监听器运行在独立的后台线程中,每次按下esc后,该线程会被raw_input()阻塞,直至用户输入内容。多次重复此操作后,监听器线程因频繁阻塞出现状态异常,无法再捕获后续的esc按键事件,导致第四次按下esc时无响应。
修改方案
将用户输入逻辑移至主线程,避免阻塞键盘监听器线程。通过线程事件控制鼠标捕获的暂停与恢复,让键盘监听器仅负责触发操作信号,不处理阻塞输入。
修改后的代码
#coding=utf-8 from pynput import keyboard from pynput import mouse import threading running = True pause_event = threading.Event() pause_event.set() # 初始状态允许捕获鼠标坐标 print('The script is capturing the coordinates of the cursor...') def get_coords(x, y): if running and pause_event.is_set(): print("Now at: {}".format((x, y))) def on_press(key): global user_input_signal if key == keyboard.Key.esc: pause_event.clear() # 暂停鼠标捕获 user_input_signal = True # 通知主线程处理用户输入 user_input_signal = False # 启动鼠标监听器 mouse_listener = mouse.Listener(on_move=get_coords) mouse_listener.start() # 启动键盘监听器 keyboard_listener = keyboard.Listener(on_press=on_press) keyboard_listener.start() try: while True: if user_input_signal: user_input_signal = False print('The script has stopped. Do you wish to continue? (y/n)') while True: answer = raw_input().strip().lower() if answer == 'y': pause_event.set() # 恢复鼠标捕获 print('The script was successfully resumed...') break elif answer == 'n': running = False print('The script has finished...') # 停止所有监听器 mouse_listener.stop() keyboard_listener.stop() break else: print('Invalid answer. Please enter "y" to continue or "n" to end the script.') if not running: break except KeyboardInterrupt: # 捕获Ctrl+C,优雅停止监听器 mouse_listener.stop() keyboard_listener.stop() # 等待监听器线程结束 mouse_listener.join() keyboard_listener.join()
修改说明
- 使用
threading.Event()实现鼠标捕获的暂停/恢复控制,避免在回调中阻塞线程。 - 键盘监听器仅设置标记信号,由主线程处理用户输入,确保监听器线程始终能响应新的键盘事件。
- 主线程负责处理用户输入逻辑,不会影响监听器的正常运行,支持无限次触发esc按键操作。
内容的提问来源于stack exchange,提问作者Anonibot
相关产品推荐
相关产品推荐

