Python如何实现按键启停跨脚本函数并解决运行阻塞问题
可直接运行的双文件实现方案
核心原理
- 原代码卡死的根本原因:同步调用
PrintNumbers()时,该函数带time.sleep的长循环会完全占住主线程,执行期间无法回到外层逻辑检测第二次按键动作。 - 之前尝试Tkinter界面卡死的原因同理:把计数循环直接放在Tk的主事件循环中,堵死了UI事件的响应通道。
- 正确的架构拆分:将耗时的计数任务放到独立子线程执行,主线程只负责响应按键事件,两者解耦后不会出现互相阻塞的问题。
代码修正
修正后的 PrintNumbers.py
import time # 全局停止标志,Python GIL 下布尔值读写可直接跨线程安全访问 stopnow = False def stopPrinting(): global stopnow stopnow = True def PrintNumbers(): global stopnow x = 0 # 测试阶段保留x<10的限制,满足计数到10自动停止的测试需求 # 实际使用时去掉x<10条件,即可实现持续运行直到收到停止指令 while x < 10 and not stopnow: x = x + 1 print(f'X is: {x}\tStopnow is {stopnow}') time.sleep(1) if __name__ == "__main__": PrintNumbers()
修正后的 main.py
import keyboard import threading import time import PrintNumbers as pN # 维护当前计数线程的状态 active_thread = None def toggle_count_task(): global active_thread # 无活跃线程时,启动新的计数任务 if active_thread is None or not active_thread.is_alive(): print("启动计数任务") # 每次启动前重置停止标志,避免上次停止状态影响新任务 pN.stopnow = False # 子线程运行计数任务,设置为守护线程,主程序退出时可自动回收 active_thread = threading.Thread(target=pN.PrintNumbers, daemon=True) active_thread.start() # 有活跃线程时,触发停止逻辑 else: print("停止计数任务") pN.stopPrinting() # 等待旧线程完全退出,避免状态冲突 active_thread.join() # 绑定F键触发任务切换 keyboard.add_hotkey('f', toggle_count_task) print("程序已就绪,按F键启动/停止计数任务") # 主线程保持运行,阻塞等待按键事件 keyboard.wait()
运行说明
- 依赖安装:执行
pip install keyboard安装按键监听库 - 权限要求:Windows环境需以管理员身份运行脚本;macOS环境需给终端开启「辅助功能」权限,否则无法捕获全局按键事件
- 效果验证:第一次按F键启动计数,计数到10自动停止;中途按F键可立即终止计数;任务停止后再按F键可重新启动整套流程。
内容的提问来源于stack exchange,提问作者Chr Isso
相关产品推荐
相关产品推荐

