PyQt:显示Python解释器输出

PyQt:显示Python解释器输出,python,pyqt4,Python,Pyqt4,我已经在我的代码中实现了,我希望它能实现我想要的。但是,我正在通过QPushButton上的连接运行一个方法,并且我希望将此方法中发生的事情通过管道传输到GUI 第一次单击按钮时,stdout出现在解释器窗口中;然而,在随后按下按钮时,stdout出现在QTextEdit中-我想打印语句或QPushButton有一些复杂之处,我不明白-如果有人能给出我需要开始更改代码的任何指针,我将永远感激 我认为这是我可以用来演示问题的最少代码量 import os, sys from PyQt4 impor

我已经在我的代码中实现了,我希望它能实现我想要的。但是,我正在通过
QPushButton
上的连接运行一个方法,并且我希望将此方法中发生的事情通过管道传输到GUI

第一次单击按钮时,
stdout
出现在解释器窗口中;然而,在随后按下按钮时,
stdout
出现在
QTextEdit
中-我想打印语句或
QPushButton
有一些复杂之处,我不明白-如果有人能给出我需要开始更改代码的任何指针,我将永远感激

我认为这是我可以用来演示问题的最少代码量

import os, sys
from PyQt4 import QtCore, QtGui 

def main(): 
  app = QtGui.QApplication(sys.argv) 
  w = MyWindow() 
  w.show() 
  sys.exit(app.exec_()) 

class MyWindow(QtGui.QWidget): 
  def __init__(self, *args): 
    QtGui.QWidget.__init__(self, *args) 
    self.runBtn = QtGui.QPushButton('Run!', self)
    self.runBtn.clicked.connect(self.runCmd)
    self.te = QtGui.QTextEdit()

    layout = QtGui.QVBoxLayout(self)
    layout.addWidget(self.runBtn)
    layout.addWidget(self.te)
    self.setLayout(layout) 

  def runCmd(self):
    print "here"
    print sys.stdout
    sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)

  def __del__(self):
    sys.stdout = sys.__stdout__

  def normalOutputWritten(self, text):
    cursor = self.te.textCursor()
    cursor.movePosition(QtGui.QTextCursor.End)
    cursor.insertText(text)
    self.te.setTextCursor(cursor)
    self.te.ensureCursorVisible()

class EmittingStream(QtCore.QObject):
  textWritten = QtCore.pyqtSignal(str)
  def write(self, text):
    self.textWritten.emit(str(text))

if __name__ == "__main__": 
  main()

您正在将信号与方法调用混合:

sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)
我不知道这是怎么回事。您应该这样做:

self.stream = EmittingStream()
self.stream.textWritten.connect(self.normalOutputWritten)
但只有一次,当你启动程序。要查看输出,请执行以下操作:

try:
   sys.stdout = self.stream

   ... code to print something ...
finally:
   sys.stdout = sys.__stdout__ # reset stdout to default

Aaron提出了一个很好的观点,但我的问题有一个比python中复杂的面向对象更简单的答案

sys.stdout = EmittingStream(textWritten=self.normalOutputWritten) 

任何打印语句之后都需要,在此之前的打印语句将被定向到标准的
stdout
,即解释器控制台。

我也不明白。。。这是从我链接到的答案中逐字逐句地提取出来的(尽管你的观点似乎有点道理——我仍在试图弄清楚PyQt的内容!)也许这是一个bug;评论说“关于堆栈溢出的答案是为了传递想法,而不是准备好使用的实现。”我尝试使用您的建议,得到了一个
AttributeError:'PyQt4.QtCore.pyqtSignal'对象没有属性“connect”
错误:我假设您的意思是
self.stream.textWrited.connect(self.normaloutputWrited)
(有效)@ChrisW:谢谢,修正了。呃……什么?如果你不允许打印任何东西,设置
sys.stdout
有什么意义?对不起,我不明白你的问题?在你的回答中,你写“在任何打印语句之后”这意味着任何东西都不会通过
EmittingStream
打印。显然,我对某些事情还不是很清楚(我不太了解PyQt,不知道该澄清什么),但在我的代码中,打印语句会被定向到stdout,直到调用
sys.stdout=EmittingStream(textWrited=self.normaloutputWrited)