如何捕获Python解释器的输出并在Text小部件中显示?

时间:2011-12-02 12:28:29

标签: python python-3.x pyqt

我有一个使用PyQt的Python程序,旨在在Windows上运行。 该程序进行了大量操作并打印了大量信息。 但是,由于我想要冻结它并且不希望出现提示屏幕,我希望所有信息都显示在主应用程序中,在QTextEdit中。 我如何使程序工作,以便从解释器获取输出并同时在textEdit上显示它,就像在真正的解释器上一样?

4 个答案:

答案 0 :(得分:36)

我假设使用“解释器的输出”,表示写入控制台或终端窗口的输出,例如使用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))

现在,在您的GUI中,将此流的实例安装到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()

答案 1 :(得分:4)

不幸的是,这个例子不适用于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 :(得分:2)

我建议你使用日志库。 http://docs.python.org/library/logging.html 您可以编写自己的日志处理程序以与QTextEdit进行通信。这是一个很好的教程,可以帮助您入门:http://pantburk.info/?blog=77

答案 3 :(得分:0)

我在此前一段时间内为PySide的终端应用程序发布了一些内容Terminal like app in PySide。如果您正在查看PyQt,那么也要检查PySide。除了许可和语法上的一些差异外,它们基本上是相同的。