Reputation: 51
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?
Upvotes: 1
Views: 9570
Reputation: 51
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:
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()
Upvotes: 4