Python input()函数切换终端焦点后无法接收输入的解决方法
解决Python input()切换终端焦点后无响应的问题
问题描述
Python脚本在等待用户输入(提示文本为Press [Enter] key to start distribution...)时,一旦切换终端窗口焦点(如切换至Parallels、打开Word文档、查看邮件等),后续按下回车键完全无响应,程序直接挂起,必须重启才能恢复。由于需要先完成后台任务再触发脚本,无法始终保持终端焦点,“保持终端焦点”的建议不符合需求,求可行解决办法。
原代码如下:
import os import glob import shutil # 假设myPath和dir_week为已定义变量 myPath = "/path/to/your/base/directory" dir_week = "WeekXX" while True: try: # 等待用户输入 input("Press [Enter] key to start distribution...").strip() # 查找MP2文件 mp2_files = glob.glob(os.path.expanduser("~/Desktop/Amboss/*.MP2")) destination_folder = os.path.join(myPath, f"TTB/TTB_Finals_Weekly/TTB_{dir_week}/Amboss_Distribution[7]/") # 复制文件到目标目录 for file in mp2_files: shutil.copy(file, destination_folder) # 转义路径中的特殊字符并统计文件数量 escaped_folder_path = glob.escape(destination_folder) number_of_MP2_files = len(glob.glob(os.path.join(escaped_folder_path, "*.MP2"))) if number_of_MP2_files != 8: raise ValueError("Number of MP2 files does not equal 8, please check MP2 files.") break except ValueError as e: print(str(e)) continue
解决方案
方法1:用sys.stdin替代input()
input()在部分终端环境下会因焦点丢失导致阻塞异常,改用直接读取标准输入流的方式可规避该问题:
import sys # 替换原input行 print("Press [Enter] key to start distribution...") sys.stdin.readline().strip()
sys.stdin.readline()直接从标准输入流读取内容,不受终端焦点切换影响,能正常捕获回车键输入。
方法2:文件触发器触发脚本
若无需手动按回车,而是后台任务完成后触发,可通过检测触发文件的存在性来启动逻辑:
import time trigger_file = os.path.expanduser("~/Desktop/Amboss/trigger.txt") while True: try: # 循环检测触发文件 while not os.path.exists(trigger_file): time.sleep(2) # 每2秒检查一次 # 删除触发文件避免重复执行 os.remove(trigger_file) # 以下为原MP2文件处理逻辑 mp2_files = glob.glob(os.path.expanduser("~/Desktop/Amboss/*.MP2")) destination_folder = os.path.join(myPath, f"TTB/TTB_Finals_Weekly/TTB_{dir_week}/Amboss_Distribution[7]/") for file in mp2_files: shutil.copy(file, destination_folder) escaped_folder_path = glob.escape(destination_folder) number_of_MP2_files = len(glob.glob(os.path.join(escaped_folder_path, "*.MP2"))) if number_of_MP2_files != 8: raise ValueError("Number of MP2 files does not equal 8, please check MP2 files.") break except ValueError as e: print(str(e)) continue
后台任务完成后,在指定路径创建trigger.txt文件即可触发脚本,完全无需依赖终端焦点。
方法3:GUI弹窗触发
若需手动触发但不想依赖终端,可使用tkinter创建简单弹窗按钮:
import tkinter as tk def start_distribution(): try: # 以下为原MP2文件处理逻辑 mp2_files = glob.glob(os.path.expanduser("~/Desktop/Amboss/*.MP2")) destination_folder = os.path.join(myPath, f"TTB/TTB_Finals_Weekly/TTB_{dir_week}/Amboss_Distribution[7]/") for file in mp2_files: shutil.copy(file, destination_folder) escaped_folder_path = glob.escape(destination_folder) number_of_MP2_files = len(glob.glob(os.path.join(escaped_folder_path, "*.MP2"))) if number_of_MP2_files != 8: raise ValueError("Number of MP2 files does not equal 8, please check MP2 files.") root.destroy() # 执行完成后关闭弹窗 except ValueError as e: print(str(e)) # 创建弹窗 root = tk.Tk() root.title("Distribution Trigger") # 设置弹窗置顶(可选) root.attributes('-topmost', True) tk.Button(root, text="Start Distribution", command=start_distribution).pack(padx=20, pady=20) root.mainloop()
弹窗可保持前台显示,无论当前焦点在哪个窗口,点击按钮即可触发脚本,完全不受终端焦点限制。
内容的提问来源于stack exchange,提问作者nwood21
相关产品推荐
相关产品推荐

