【发布时间】:2021-10-13 13:36:20
【问题描述】:
我对 python 和 tkinter 还很陌生。我正在构建一个 GUI 来管道使用多个外部 .exe 程序的进程我希望能够通知用户其中一个 .exe 进程已经启动或停止,因为它们可能需要很长时间,我希望用户能够能够知道它当前在进程中的哪个位置。
使用我当前的代码,文本框更新会在所有内容结束时同时发生,而不是在每个步骤之后发生。有没有办法让这个更新在每一步都发生,或者有没有我不知道的更好的方法?我愿意打开命令行并打印到它。
import tkinter as tk
import subprocess as s
root = tk.Tk()
root.minsize(650,250)
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
container = tk.Frame(root).grid(row=0, column=0)
exe_1_path = tk.StringVar(root, value = 'C:\\Users\\Process_data_step_1.exe')
exe_2_path = tk.StringVar(root, value = 'C:\\Users\\Process_data_step_2.exe')
exe_3_path = tk.StringVar(root, value = 'C:\\Users\\Process_data_step_3.exe')
config_file_path = tk.StringVar(root, value = 'C:\\Users\\Config.txt')
output_path = tk.StringVar(root, value = 'C:\\Users\\Output')
def start_processing():
# notifu user that we are starting to process the data
output_window.insert(tk.END, 'Starting to process data for exe1.\n')
# I want the textbox to update here
s.check_call([exe_1_path.get(), '-c', config_file_path.get(), 'o', output_path.get])
output_window.insert(tk.END, 'Finished processing data for exe1.\n')
# I want the textbox to update and here
output_window.insert(tk.END, 'Starting to process data for exe2.\n')
# I want the textbox to update and here
s.check_call([exe_2_path.get(), '-c', config_file_path.get(), 'o', output_path.get])
output_window.insert(tk.END, 'Finished processing data for exe2.\n')
# I want the textbox to update and here
output_window.insert(tk.END, 'Starting to process data for exe3.\n')
# I want the textbox to update and here
s.check_call([exe_3_path.get(), '-c', config_file_path.get(), 'o', output_path.get])
output_window.insert(tk.END, 'Finished processing data for exe3.\n')
# I want the textbox to update and here
start_button = tk.Button(container, text='Start', width=10, command = start_processing)
start_button.grid(row = 0, pady=10, padx=20)
output_window = tk.Text(root, height = 10, width = 75, bg = 'black', fg = 'white')
output_window.grid(row = 1, pady=10, padx=20)
root.mainloop()
【问题讨论】:
-
调用
check_call()将使您的脚本挂起或冻结,直到它返回。您需要定期检查子流程的状态并相应地更新 GUI。为了帮助您,您需要发布更完整的minimal reproducible example (MRE)。 -
您可以在每个
check_call()之前添加output_window.update_idletasks()。 -
@acw1668 在
check_call运行时不会挂起tkinter 吗?我的意思是它会比现在好一些,但仍然会冻结 -
@Matiiss OP 没有询问冻结问题。
-
@acw1668 这正是我想要的,谢谢。我不担心 tkinter 挂起,而子进程工作只是想要一种通知用户进度的方法。
标签: python tkinter concurrency subprocess