【发布时间】:2012-01-11 11:35:21
【问题描述】:
我有一个带有 PyQt 的 Python 程序,旨在在 Windows 上运行。 该程序进行大量操作并打印大量信息。 但是因为我想冻结它并且不希望出现提示屏幕,所以我希望所有这些信息都出现在主应用程序中,在 QTextEdit 左右。 我怎样才能使程序工作,以便它从解释器获取输出并同时在 textEdit 上显示它,就像它在真正的解释器上一样?
【问题讨论】:
标签: python python-3.x pyqt
我有一个带有 PyQt 的 Python 程序,旨在在 Windows 上运行。 该程序进行大量操作并打印大量信息。 但是因为我想冻结它并且不希望出现提示屏幕,所以我希望所有这些信息都出现在主应用程序中,在 QTextEdit 左右。 我怎样才能使程序工作,以便它从解释器获取输出并同时在 textEdit 上显示它,就像它在真正的解释器上一样?
【问题讨论】:
标签: python python-3.x pyqt
不幸的是,该示例不适用于 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)
【讨论】:
sys.stdout.textWritten.connect(self.write2Console)
我不久前在Terminal like app in PySide 上发布了一些有关 PySide 终端应用程序的内容。如果您正在查看 PyQt,那么还要检查 PySide。除了许可和语法上的一些差异之外,它们基本上是相同的。
【讨论】:
我假设“解释器的输出”是指写入控制台或终端窗口的输出,例如使用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()
【讨论】:
QObject 的子类,并具有由write() 发出的textWritten 信号。然后,我只需将此信号与窗口中的一个插槽连接,该插槽将文本附加到QTextEdit。优点:可以对正常输出和错误输出进行不同的格式化;后者使用红色文本颜色。
self.textEdit.append(str(text))是不是错了?
sys.stderr,然后尝试捕获sys.stdout。这样,您的流代码中的任何异常都会照常显示。事实上,如果您的write() 函数引发异常,您可能会陷入无限循环!
self.textEdit.append(str(text)),我知道这是不对的。我怎样才能到达另一个文件的另一个类中的 textEdit?附言是的,我删除了 stderr 部分,谢谢。
我建议你使用日志库。 http://docs.python.org/library/logging.html 您可以编写自己的日志处理程序来与 QTextEdit 进行通信。这是一个很好的教程,可以帮助您入门:http://pantburk.info/?blog=77
【讨论】: