Python中如何停止运行在后台线程的pynput Listener监听器?
问题修复与实现方案
原有代码问题
- 缺失必要导入:没有导入
time模块,也没有导入pynput.keyboard实例,on_press回调中调用的keyboard.is_pressed无来源 - 逻辑阻塞问题:
with Listener(...) as listener配合listener.join()会阻塞当前线程,你写的stopThreads状态判断逻辑永远无法执行 - 变量作用域问题:
listener仅在if分支内部定义,elif分支调用listener.stop()会触发未定义报错 - 冗余逻辑问题:无限循环反复创建Listener实例,导致按键事件无法正常捕获
正确实现代码
from pynput.keyboard import Key, Listener from threading import Thread import time stop_threads = False listener = None def on_press(key): try: if key.char == 'a': print("pressed a") except AttributeError: # 特殊功能键没有char属性,跳过处理即可 pass # 如果需要靠全局变量直接终止监听,加以下判断即可 # if stop_threads: # return False def starting(): global listener # 直接创建监听器并启动,Listener本身就是线程类 listener = Listener(on_press=on_press) listener.start() # 阻塞等待监听器终止信号 listener.join() # 启动后台监听线程,设置为守护线程避免进程残留 t = Thread(target=starting, daemon=True) t.start() # 模拟业务运行逻辑,5秒后停止监听 time.sleep(5) print("stop") stop_threads = True # 调用stop方法直接终止监听器 if listener: listener.stop()
实现说明
- Listener本身继承自Thread类,不需要额外套while循环控制运行,调用
start()后就会在后台独立线程中监听按键事件 - 停止监听的两种方式:直接调用Listener实例的
stop()方法,或者在on_press/on_release回调中返回False,监听器收到False返回值就会自动停止 - 线程设置为daemon守护线程后,主线程退出时监听线程会跟着自动销毁,不会出现进程后台残留的问题
内容的提问来源于stack exchange,提问作者Shavow
相关产品推荐
相关产品推荐

