Как захватить вывод интерпретатора Python и показать в текстовом виджете?

У меня есть программа на Python с PyQt, предназначенная для работы в Windows. Эта программа делает много операций и печатает много информации. Но поскольку я хочу заморозить его и не хочу, чтобы экран подсказки отображался, я хочу, чтобы вся эта информация отображалась в основном приложении в QTextEdit или так. Как я могу заставить программу работать, чтобы она получала выходные данные от интерпретатора и одновременно отображала ее на текстовом элементе, как это делается на реальном интерпретаторе?

Ответы

Ответ 1

Я предполагаю, что с "выходом из интерпретатора" вы имеете в виду вывод, записанный в консоль или окно терминала, например, вывод, полученный с помощью print().

Все выходные данные консоли, созданные Python, записываются в выходные потоки программы sys.stdout (нормальный вывод) и sys.stderr (вывод ошибок, например трассировки исключений). Это файловые объекты.

Вы можете заменить эти потоки своим файлоподобным объектом. Вся ваша пользовательская реализация должна предоставить функцию write(text). Предоставляя свою собственную реализацию, вы можете перенаправить весь вывод на ваш виджет:

class MyStream(object):
    def write(self, text):
        # Add text to a QTextEdit...

sys.stdout = MyStream()
sys.stderr = MyStream()

Если вам понадобится reset эти потоки, они по-прежнему доступны как sys.__stdout__ и sys.__stderr__:

sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__

Обновление

Вот какой рабочий код для PyQt4. Сначала определите поток, который сообщает данные, записанные ему с сигналом Qt:

from PyQt4 import QtCore

class EmittingStream(QtCore.QObject):

    textWritten = QtCore.pyqtSignal(str)

    def write(self, text):
        self.textWritten.emit(str(text))

Теперь в вашем графическом интерфейсе установите экземпляр этого потока в sys.stdout и подключите сигнал textWritten к слоту, который записывает текст в 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()

Ответ 2

Я предлагаю вам использовать библиотеку регистрации. http://docs.python.org/library/logging.html Вы можете написать свой собственный обработчик журналов для связи с QTextEdit. Вот хороший учебник, который поможет вам начать: http://pantburk.info/?blog=77

Ответ 3

К сожалению, пример не работает с PySide. Он дает следующую ошибку:

sys.stdout = EmittingStream(textWritten=self.write2Console)
AttributeError: 'textWritten()' is not a Qt property or a signal

Нам нужно сделать следующие изменения для работы с PySide:

sys.stdout = EmittingStream()
self.connect(sys.stdout,QtCore.SIGNAL('textWritten(QString)'),self.write2Console)

Ответ 4

Я разместил некоторое приложение для терминала для PySide на этом некоторое время назад Terminal как приложение в PySide. Если вы смотрите на PyQt, проверьте также PySide. Они в основном одни и те же, кроме лицензирования и несколько различий в синтаксисе.