如何在main.py中同时运行两个含无限循环的Python监听脚本?
解决Python多监听器阻塞问题:同时运行键盘和鼠标监听
这问题太常见了!你之所以只能运行第一个脚本,核心原因是listener.join()是阻塞式调用——它会暂停当前线程,直到监听器停止运行。而你的监听器是无限循环的(除非手动干预),所以第一个监听器的join()永远不会结束,程序根本没机会执行第二个监听器的代码。
解决思路:用多线程让两个监听器并行运行
我们需要把每个监听器的逻辑封装成独立函数,然后在主线程中用线程分别启动它们。这样两个阻塞的join()就会在各自的线程里运行,不会互相卡住。
步骤1:修改你的监听脚本,封装成函数
原来的脚本直接在模块级别执行了listener.join(),导致import时就会阻塞。我们把监听逻辑封装成可调用的函数:
修改后的keyboard_listener.py:
from pynput.keyboard import Key, Listener def start_keyboard_listener(): def on_press(key): print(f"Pressed key: {key}") with Listener(on_press=on_press) as listener: listener.join()
修改后的mouse_listener.py:
from pynput.mouse import Listener def start_mouse_listener(): def on_click(x, y, button, pressed): print(f"Mouse button: {button}, Pressed: {pressed}") with Listener(on_click=on_click) as listener: listener.join()
步骤2:在main.py中用线程启动两个监听器
使用Python内置的threading模块,创建两个线程分别运行两个监听器函数:
import threading from keyboard_listener import start_keyboard_listener from mouse_listener import start_mouse_listener if __name__ == "__main__": # 创建线程对象,指定要运行的目标函数 keyboard_thread = threading.Thread(target=start_keyboard_listener) mouse_thread = threading.Thread(target=start_mouse_listener) # 启动两个线程 keyboard_thread.start() mouse_thread.start() # 必须添加这两行:让主线程等待子线程结束 # 如果不写,主线程会直接退出,导致两个监听线程也跟着终止 keyboard_thread.join() mouse_thread.join()
为什么这样能行?
每个线程都是独立的执行流,start()会启动线程并运行目标函数,而join()会让主线程等待子线程完成。这样两个监听器的阻塞逻辑分别在各自的线程里运行,就能同时监听键盘和鼠标事件了。
额外提示:优雅停止监听器
如果需要手动停止监听器,可以在回调函数里添加停止条件,比如按下ESC键时退出:
# 在键盘监听的on_press函数中添加: def on_press(key): print(f"Pressed key: {key}") if key == Key.esc: # 返回False会触发监听器停止 return False
这样按下ESC键就能停止键盘监听器,对应的线程也会自动结束。
内容的提问来源于stack exchange,提问作者Saeed Shafiee
相关产品推荐
相关产品推荐

