I have to call a legacy Bash program and output the results to a Qt window. The problem is the subprocess the Bash command is executed in doesn’t return each output line as they happen; the subprocess waits until the entire Bash command is finished, then it dumps everything to the window. Thus, if the Bash command takes a long time, the user may think the system is frozen.
I can get the subprocess to print each line via a print(output.readlin()) to a normal terminal. But I can’t do it within Qt. I have tried a number of different examples and either they don’t work or continue to dump the results at the end of the process.
I don’t know if this a problem that an unknown Qt module might help me with or if it’s just something with how Python deals w/ subprocess calls to Bash commands, like it’s running a batch job and only returning results once the batch is done.
Here is the trouble code I’m working with:
self.console = OutputConsole() out = subprocess.run(["bash", "-c", f"source path_to_setup_file -r && cd parent_directory && build_project_command"], stderr=subprocess.STDOUT, stdout=subprocess.PIPE) self.console.on_update_text(out.stdout.decode()) class OutputConsole(QWidget): """Collects output data (sys.stdout) from subprocess calls to ocpidev. Prints the output to the console view.""" process: QTextEdit def __init__(self, process: QTextEdit) -> None: """Create the process that manages text editing on the console""" super().__init__() sys.stdout = Stream() self.process = process self.process.moveCursor(QTextCursor.Start) self.process.ensureCursorVisible() self.process.setLineWrapColumnOrWidth(1000) self.process.setLineWrapMode(QTextEdit.FixedPixelWidth) def on_update_text(self, text: str) -> None: """Add new text to the console as stdout gets more data""" cursor: QTextCursor = self.process.textCursor() cursor.movePosition(QTextCursor.End) cursor.insertText(text) self.process.setTextCursor(cursor) self.process.ensureCursorVisible() def __del__(self) -> None: """Reset sys.stdout to normal functionality""" sys.stdout = sys.__stdout__