I have a Tkinter GUI program that I would like to update a text Frame on with output from a called process. I managed to make it work pretty well using threading and subprocess, with the ‘run’ button bound to a method to create a thread and call Popen within it.
def template_thread(self):
threading.Thread(target=self.run_template, daemon=True).start()
The run_template method calls main.py with the path to a config file as an arg:
p = subprocess.Popen([EXE, FIRST_RUN, os.path.join(self.output.get(), 'runtime.ini')],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1, universal_newlines=True)
while p.poll() is None:
print('here')
#p.stdout.flush()
#p.stderr.flush()
msg = p.stdout.readline()
err = p.stderr.readline()
if msg:
self.output_window.insert(tk.END, msg + "n")
if err:
with open(os.path.join(self.output.get(), 'LOG.txt'), 'a') as log:
log.write(err)
This works perfectly whenever I test it within Pycharm, but as soon as I try to run it from anywhere else, the behavior changes to blocking on the readline() until the process has finished, and then flushing the whole stdout to the text Frame at once. I think from other similar but very old questions that it has to do with how the buffer is set by each program and somehow the IDE terminal is setting the buffer to flush and newlines but can’t find a solution. Running with ‘-u‘ as an argument didn’t seem to have an effect and neither did adding ‘flush=True‘ to the first print statement. The program works as needed otherwise and the mainloop is not interrupted as I can see the focus on my widgets changing so I’m a little stumped. Running on Windows if that changes anything. Any help is appreciated!
1