我正在构建一个GUI,以用作Python的交互式“曲线拟合工具”。我以QTextEdit小部件的形式添加了一个“记录”窗口(处于只读模式),该窗口显示了代码的相关输出-优化参数,警告等信息。这是通过重定向sys.stdout和sys.stderr来完成的。通过类似这样的操作到QTextEdit小部件:
class Stream(QtCore.QObject):
newText = QtCore.pyqtSignal(str)
def write(self, text):
self.newText.emit(str(text))
class MyApp(QtWidgets.QMainWindow):
def __init__(self):
# Other stuff here...
self.outputWidget = QtWidgets.QTextEdit();
self.outputWidget.setReadOnly(True)
vLayout.addWidget(self.outputWidget)
sys.stderr = Stream(newText=self.onUpdateText)
sys.stdout = Stream(newText=self.onUpdateText)
我想做的是在用户完成某些操作(例如更改拟合功能等)之后,清除日志记录窗口,然后继续打印出现的所有内容,以防止以前的拟合结果引起混淆。
最明显的事情是这样的:
def onUpdateText(self, text):
self.outputWidget.clear()
self.outputWidget.moveCursor(QtGui.QTextCursor.End,QtGui.QTextCursor.MoveAnchor)
self.outputWidget.insertPlainText(text)
self.outputWidget.ensureCursorVisible()
但是-这只会导致窗口小部件中的所有文本都被清除,而没有其他任何显示(或者,什么也没有显示)。删除clear()
调用可以使其正常工作,尽管无需清除以前的输出。
在放入其他文本之前立即清除窗口小部件文本的正确方法是什么?
编辑:
以下是可重现的示例:
import sys
from PyQt5 import QtGui, QtCore,QtWidgets
from PyQt5.QtCore import pyqtSlot
import PyQt5.QtCore as qtcore
class Stream(QtCore.QObject):
newText = QtCore.pyqtSignal(str)
def write(self, text):
self.newText.emit(str(text))
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self._main = QtWidgets.QWidget()
self.setCentralWidget(self._main)
vLayout = QtWidgets.QVBoxLayout(self._main);
self.inputWidget = QtWidgets.QLineEdit();
self.inputWidget.setText("Type something here.")
self.inputWidget.textEdited.connect(self.textChanged)
vLayout.addWidget(self.inputWidget)
self.outputWidget = QtWidgets.QTextEdit();
self.outputWidget.setReadOnly(True)
vLayout.addWidget(self.outputWidget)
sys.stdout = Stream(newText=self.onUpdateText)
def __del__(self):
sys.stdout = sys.__stdout__
def onUpdateText(self, text):
self.outputWidget.clear()
self.outputWidget.insertPlainText(text)
self.outputWidget.ensureCursorVisible()
def textChanged(self,newstr):
print(newstr)
if __name__ == "__main__":
qapp = QtWidgets.QApplication(sys.argv)
app = ApplicationWindow()
app.show()
qapp.exec_()
答案 0 :(得分:1)
导致此问题的原因是print()
方法在缓冲区2上写入了文本:传递给打印的文本和结尾行(\ n),您可以验证是否传递了字节。因此,第一次书写会删除先前的文字并将其添加到新文本中,而在第二次书写中,先前的文字会被删除,并导致看不见的“ \ n”导致明显的非书写。
def onUpdateText(self, text):
self.outputWidget.insertPlainText(str(text.encode()))
输出:
因此,根据您的实际应用,有几种解决方案:
sys.stdout.write()
代替print()
。def onUpdateText(self, text):
self.outputWidget.clear()
self.outputWidget.insertPlainText(text)
def textChanged(self, newstr):
sys.stdout.write(newstr)
def onUpdateText(self, text):
if text != "\n":
self.outputWidget.clear()
self.outputWidget.insertPlainText(text)
def textChanged(self, newstr):
print(newstr)
或
def onUpdateText(self, text):
if text != "\n":
self.outputWidget.clear()
self.outputWidget.insertPlainText(text)
def textChanged(self, newstr):
print(newstr)