Python tkinter:在子进程调用之间更新GUI

Python tkinter:在子进程调用之间更新GUI,python,tkinter,subprocess,Python,Tkinter,Subprocess,我编写了一个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.

我编写了一个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()
当按下按钮时调用进程

我还尝试了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;而我发现了一个肮脏的解决方案: 我在每次subprocess.call之前调用root.update

为了确保在处理过程中没有按下任何按钮,根据快速谷歌搜索,root.update似乎有问题,我在启动子流程之前禁用了所有按钮

像这样:

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()
我找到了一个肮脏的解决方案: 我在每次subprocess.call之前调用root.update

为了确保在处理过程中没有按下任何按钮,根据快速谷歌搜索,root.update似乎有问题,我在启动子流程之前禁用了所有按钮

像这样:

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

文本区域的更新应该足够了。一个问题是:可能是复制粘贴错误,但为什么app=app不引用root?你能粘贴完整的代码吗?谢谢你的回答。不幸的是,这似乎还不够。GUI在处理过程中未更新。应用程序未引用根,因为我没有构造函数。这有必要吗?完整的代码相当长,但我认为最重要的部分包含在第一篇文章中。嗯,我不知道为什么这不是刷新,但我不确定更新标签文本是否是所谓的空闲任务。您是否可以在不使用StringVar的情况下直接使用以下命令进行测试:label.configuretext=processing?谢谢,但还是一样的。它会切换到处理文件1和处理文件2,但随后会冻结,直到全部完成!。是否有可能.exe没有正确终止?您可以通过检查可执行文件的returncode是否如预期的那样来检查执行的结束:subprocess.call返回它,因此您可以将它与0或预期值进行比较。textarea的更新应该足够了。一个问题是:可能是复制粘贴错误,但为什么app=app不引用root?你能粘贴完整的代码吗?谢谢你的回答。不幸的是,这似乎还不够。GUI在处理过程中未更新。应用程序未引用根,因为我没有构造函数。这有必要吗?完整的代码相当长,但我认为最重要的部分包含在第一篇文章中。嗯,我不知道为什么这不是刷新,但我不确定更新标签文本是否是所谓的空闲任务。您是否可以在不使用StringVar的情况下直接使用以下命令进行测试:label.configuretext=processing?谢谢,但还是一样的。它会切换到处理文件1和处理文件2,但随后会冻结,直到全部完成!。是否有可能.exe没有正确终止?您可以通过检查可执行文件的returncode是否如预期的那样来检查执行的结束:subprocess.call返回它,因此您可以将它与0或预期值进行比较。