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