I have a program in Python with PyQt, designed to run on Windows. This program makes a lot of operations and prints a lot of info. But as I want to freeze it and don't want the prompt screen to appear, I want that all that info appears in the main application, in a QTextEdit or so. How can i make the program work so it gets the output from the interpreter and shows it on the textEdit at the same time, just like it does on the real interpreter?
I assume that with "output from the interpreter", you mean output written to the console or terminal window, such as output produced with print()
.
All console output produced by Python gets written to the program's output streams sys.stdout
(normal output) and sys.stderr
(error output, such as exception tracebacks). These are file-like objects.
You can replace these streams with your own file-like object. All your custom implementation must provide is a write(text)
function. By providing your own implementation, you can forward all output to your widget:
class MyStream(object):
def write(self, text):
# Add text to a QTextEdit...
sys.stdout = MyStream()
sys.stderr = MyStream()
If you ever need to reset these streams, they are still available as sys.__stdout__
and sys.__stderr__
:
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
Update
Here is some working code for PyQt4. First define a stream that reports data written to it with a Qt signal:
from PyQt4 import QtCore
class EmittingStream(QtCore.QObject):
textWritten = QtCore.pyqtSignal(str)
def write(self, text):
self.textWritten.emit(str(text))
Now, in your GUI, install an instance of this stream to sys.stdout
and connect the textWritten
signal to a slot that writes the text to a QTextEdit
:
# Within your main window class...
def __init__(self, parent=None, **kwargs):
# ...
# Install the custom output stream
sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)
def __del__(self):
# Restore sys.stdout
sys.stdout = sys.__stdout__
def normalOutputWritten(self, text):
"""Append text to the QTextEdit."""
# Maybe QTextEdit.append() works as well, but this is how I do it:
cursor = self.textEdit.textCursor()
cursor.movePosition(QtGui.QTextCursor.End)
cursor.insertText(text)
self.textEdit.setTextCursor(cursor)
self.textEdit.ensureCursorVisible()