Python tkinter:在子进程调用之间更新 GUI
我编写了一个 GUI,它多次调用 .cmd 文件(使用不同的参数)
class App:
def process(self):
for filename in os.listdir(path):
subprocess.call(['script.cmd', filename])
self.output('processed ' + filename)
def output(self, line):
self.textarea.config(state = NORMAL)
self.textarea.tag_config("green", background="green", foreground="black")
self.textarea.insert(END, line, ("green"))
self.textarea.yview(END)
self.textarea.config(state = DISABLED)
self.textarea.update_idletasks()
root = Tk()
app = App()
app.build_gui(root)
app.pack_gui(root)
root.mainloop()
按下按钮时调用 process()
我还尝试了 subprocess.Popen() 和旧的 os.spawnv() 总是一样的。处理文件时 GUI 没有反应。仅在处理完所有文件后,GUI 才会使用所有“已处理 XYZ”消息进行更新。
update_idletasks() 不应该在每次子进程调用后更新 GUI 吗?
谢谢
编辑: 我将问题缩小到这个简单的代码:
from Tkinter import *
import subprocess
file_list = ['file1', 'file2', 'file3', 'file4', 'file5']
def go():
labeltext.set('los')
for filename in file_list:
labeltext.set('processing ' + filename + '...')
label.update_idletasks()
proc = subprocess.call(["C:\\test\\process.exe", filename])
labeltext.set('all done!')
root = Tk()
Button(root, text="Go!", command=go).pack(side=TOP)
labeltext = StringVar()
labeltext.set('Press button to start')
label = Label(root, textvariable=labeltext)
label.pack(side=TOP)
root.mainloop()
现在,脚本是否正常工作取决于 process.exe。如果我编写一个简单的忙循环C程序(例如process.exe的源代码:int i=0; while(i<1e9){ i++; }),则GUI会随着每个文件1-5而更新。当我调用我想要使用的原始 .exe 文件时,它显示“正在处理文件 1”并切换到“正在处理文件 2”,但然后冻结直到程序终止(“全部完成!”)。
我真的不明白这里发生了什么。显然这与调用的过程有关。有人有想法吗?
I programmed a GUI that calls a .cmd file several times (with different parameters)
class App:
def process(self):
for filename in os.listdir(path):
subprocess.call(['script.cmd', filename])
self.output('processed ' + filename)
def output(self, line):
self.textarea.config(state = NORMAL)
self.textarea.tag_config("green", background="green", foreground="black")
self.textarea.insert(END, line, ("green"))
self.textarea.yview(END)
self.textarea.config(state = DISABLED)
self.textarea.update_idletasks()
root = Tk()
app = App()
app.build_gui(root)
app.pack_gui(root)
root.mainloop()
process() is called when pressing a button
I also tried subprocess.Popen() and the old os.spawnv()
It's always the same. The GUI is not reacting when processing the files. Only after all files have been processed, the GUI is updated with all the 'processed XYZ' messages.
Shouldn't update_idletasks() update the GUI after every subprocess call?
Thank you
edit:
I narrowed the problem to this simple code:
from Tkinter import *
import subprocess
file_list = ['file1', 'file2', 'file3', 'file4', 'file5']
def go():
labeltext.set('los')
for filename in file_list:
labeltext.set('processing ' + filename + '...')
label.update_idletasks()
proc = subprocess.call(["C:\\test\\process.exe", filename])
labeltext.set('all done!')
root = Tk()
Button(root, text="Go!", command=go).pack(side=TOP)
labeltext = StringVar()
labeltext.set('Press button to start')
label = Label(root, textvariable=labeltext)
label.pack(side=TOP)
root.mainloop()
Now it depends on the process.exe if the script works properly. If I write a simple C program with busy-looping (e.g. source code of process.exe: int i=0; while(i<1e9){ i++; }), the GUI is updated with every file1-5. When I call the original .exe-file I wanted to use, it displays "processing file1" and switches to "processing file2" but then freezes until program termination ("all done!").
I dont really understand whats up here. Obviously it has something to do with the process called. Does anyone have an idea?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我找到了一个肮脏的解决方案:
我在每个 subprocess.call() 之前调用 root.update() 。
为了确保在处理过程中没有按下任何按钮(根据快速谷歌搜索,这似乎是 root.update() 的问题),我在子进程启动之前将它们全部禁用,
如下所示:
I found a dirty solution:
I call root.update() before every subprocess.call().
To make sure that no buttons are pressed during processing (that seems to be a problem with root.update() according to a quick google search), I disable them all before the subprocesses are started
like this: