I have a GUI program guy.py
(that uses tkinter) and a command line script script.py
. I want to launch the script from the program and write its output to a textbox in the GUI. Because the script takes quite some time to run (up to 15 minutes), and I want to monitor it, I want the script to write the output in real time inside the textbox, while it's being written, not just when it has finished executing.
I've found some other questions dealing with this problem. Here is the code of gui.py
I've developed until now (the real code is too big to post here, but here's the most important part)
import tkinter as tk
# redirector class
class StdoutRedirector:
def __init__(self, textbox):
self.textbox = textbox
def write(self, str):
self.textbox.insert(tk.END, str)
# gui application
class GuiApp:
def __init__():
self._out = StdoutRedirector(self.builder.get_object('textbox1')) # this just takes a reference to the tkinter text
def button_callback(self):
sys.stdout = self._out
print("test") # this will print to the textbox
subprocess.Popen(['python3', 'script.py']) # this will not print to the textbox
This will print the output to the "normal" output, so I've tried telling subprocess what to use as stdout, by changing the last line to
subprocess.Popen(['python3', 'script.py'], stdout=self._out)
This results in an exception, because (differently from print()
), Popen()
needs a file descriptor. Of course giving a fileno
of 1 will just print to stdout, giving any other number will throw an error
File "/usr/lib/python3.8/tkinter/__init__.py", line 1892, in __call__
return self.func(*args)
File "./guy.py", line 64, in convert_sdatb
subprocess.Popen(['python3', 'test_subprocess.py'], stdout=self._out)
File "/usr/lib/python3.8/subprocess.py", line 808, in __init__
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "/usr/lib/python3.8/subprocess.py", line 1489, in _get_handles
c2pwrite = stdout.fileno()
AttributeError: 'StdoutRedirector' object has no attribute 'fileno'
How can I make that the output of my script is redirected in real time (as it's written) directly in my class?