Python tkinter:在子进程调用之间更新 GUI [英] Python tkinter: Update GUI between subprocess calls

查看:36
本文介绍了Python tkinter:在子进程调用之间更新 GUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个 GUI,它多次调用 .cmd 文件(使用不同的参数)

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() 在按下按钮时被调用

process() is called when pressing a button

我也试过 subprocess.Popen() 和旧的 os.spawnv()它总是一样的.GUI 在处理文件时没有反应.只有在处理完所有文件后,GUI 才会更新为所有已处理的 XYZ"消息.

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.

update_idletasks() 不应该在每次子进程调用后更新 GUI 吗?

Shouldn't update_idletasks() update the GUI after every subprocess call?

谢谢

我将问题缩小到这个简单的代码:

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()

现在它取决于 process.exe 脚本是否正常工作.如果我用忙循环编写一个简单的 C 程序(例如 process.exe 的源代码:int i=0; while(i<1e9){ i++; }),GUI 会随着每个文件 1-5 更新.当我调用我想要使用的原始 .exe 文件时,它显示正在处理文件 1"并切换到正在处理文件 2",但随后会冻结直到程序终止(全部完成!").

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?

推荐答案

我找到了一个肮脏的解决方案:我在每个 subprocess.call() 之前调用 root.update().

I found a dirty solution: I call root.update() before every subprocess.call().

为了确保在处理过程中没有按下任何按钮(根据谷歌的快速搜索,这似乎是 root.update() 的问题),我在子进程启动之前将它们全部禁用

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

像这样:

from Tkinter import *
import subprocess

file_list = ['file1', 'file2', 'file3', 'file4', 'file5']

def button():
    b_process.configure(state=DISABLED)
    go()
    b_process.configure(state=NORMAL)

def go():
    for filename in file_list:
        label.configure(text="processing " + filename)
        root.update()

        proc = subprocess.call(["C:\\DTNA\\stat\\run.exe", filename])
        print 'process terminated with return code ' + str(proc)     
    label.configure(text="all done!")

root = Tk()

b_process = Button(root, text="Go!", command=button)
b_process.pack(side=TOP)

label = Label(root, text='Press button to start')
label.pack(side=TOP)

root.mainloop()

这篇关于Python tkinter:在子进程调用之间更新 GUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆