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

2024-04-19 19:53:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我编写了一个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() 总是一样的。图形用户界面在处理文件时没有反应。只有在处理完所有文件后,才会使用所有“已处理的XYZ”消息更新GUI。

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文件时,它显示“processing file1”,并切换到“processing file2”,但随后冻结,直到程序终止(“all done!”)。

我真的不明白上面是什么。显然,这与调用的过程有关。有人知道吗?


Tags: 文件selfconfigdefupdateguigreenroot
1条回答
网友
1楼 · 发布于 2024-04-19 19:53:53

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

为了确保在处理过程中没有按下任何按钮(根据google的快速搜索,这似乎是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()

相关问题 更多 >