1

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?

Mauro F.
  • 287
  • 2
  • 11
  • 3
    You would need to specify `stdout=subprocess.PIPE`, and then periodically call `.read()` on that pipe and write to your textbox. – jasonharper Apr 19 '22 at 15:35

0 Answers0