Как захватить вывод интерпретатора Python и показать в текстовом виджете? - PullRequest
21 голосов
/ 02 декабря 2011

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

Ответы [ 4 ]

37 голосов
/ 02 декабря 2011

Я предполагаю, что под «выводом из интерпретатора» вы подразумеваете вывод, записанный в консоль или окно терминала, такой как вывод, полученный с помощью 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()

Если вам когда-нибудь понадобится сбросить эти потоки, они все еще доступны как 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()
4 голосов
/ 09 декабря 2013

К сожалению, пример не работает с 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)
2 голосов
/ 02 декабря 2011

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

0 голосов
/ 09 декабря 2013

Некоторое время назад я опубликовал кое-что для терминального приложения для PySide Терминальное приложение в PySide . Если вы смотрите на PyQt, проверьте также и PySide. В основном это одно и то же, за исключением лицензирования и нескольких различий в синтаксисе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...