如何清除QTextEdit的文本并立即插入新文本
How to clear the text of QTextEdit and immediately insert new text
我正在构建一个 GUI 作为 "curve fitting tool" Python 的交互式。我以 QTextEdit 小部件(只读模式)的形式添加了一个 "logging" window,它显示代码的相关输出 - 例如优化参数、警告等。这是通过重定向 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)
我想做的是在用户完成某些事情后(比如更改拟合函数等)清除日志记录 window 然后继续打印出现的任何内容以防止与以前的拟合混淆.
最明显的事情是这样的:
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_()
问题是因为print()
方法在buffer 2 texts上写入:传递给print的文本和endline("\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)
我正在构建一个 GUI 作为 "curve fitting tool" Python 的交互式。我以 QTextEdit 小部件(只读模式)的形式添加了一个 "logging" window,它显示代码的相关输出 - 例如优化参数、警告等。这是通过重定向 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)
我想做的是在用户完成某些事情后(比如更改拟合函数等)清除日志记录 window 然后继续打印出现的任何内容以防止与以前的拟合混淆.
最明显的事情是这样的:
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_()
问题是因为print()
方法在buffer 2 texts上写入:传递给print的文本和endline("\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)