QTextedit查找替换性能
QTextedit find and replace performance
我正在开发一个文本编辑器我正在使用 Qt4.8/Pyqt 特别是 QTextedit 对象,在 Windows 7 上使用 python 2.7
考虑以下代码(非原创)
def doReplaceAll(self):
# Replace all occurences without interaction
# Here I am just getting the replacement data
# from my UI so it will be different for you
old=self.searchReplaceWidget.ui.text.text()
new=self.searchReplaceWidget.ui.replaceWith.text()
# Beginning of undo block
cursor=self.editor.textCursor()
cursor.beginEditBlock()
# Use flags for case match
flags=QtGui.QTextDocument.FindFlags()
if self.searchReplaceWidget.ui.matchCase.isChecked():
flags=flags|QtGui.QTextDocument.FindCaseSensitively
# Replace all we can
while True:
# self.editor is the QPlainTextEdit
r=self.editor.find(old,flags)
if r:
qc=self.editor.textCursor()
if qc.hasSelection():
qc.insertText(new)
else:
break
# Mark end of undo block
cursor.endEditBlock()
这适用于几百行文本。但是当我有很多文本时,说 10000 到 100000 行文本全部替换是非常慢的,以至于无法使用,因为编辑器的速度很快就会变慢。
难道我做错了什么。为什么 QTextEdit 这么慢,我尝试了 QplaingTextEdit 也没有太多运气。有什么建议吗?
如果不进行分析,您将很难准确找到减速的原因,但这可能与以下几个因素有关:
PyQT 确实与其 C 库相关联,在两者之间处理数据可能会导致速度下降。
但请注意,您不仅在更改该代码中的文本,还在 text/window.
中重新定位光标
我可以建议的最大加速是,如果您正在进行全局搜索和替换,请将所有文本拉入 python,使用 python 进行替换,然后重新插入:
def doReplaceAll(self):
# Replace all occurences without interaction
# Here I am just getting the replacement data
# from my UI so it will be different for you
old=self.searchReplaceWidget.ui.text.text()
new=self.searchReplaceWidget.ui.replaceWith.text()
# Beginning of undo block
cursor=self.editor.textCursor()
cursor.beginEditBlock()
text = self.editor.toPlainText()
text = text.replace(old,new)
self.editor.setPlainText(text)
# Mark end of undo block
cursor.endEditBlock()
根据 QTBUG-3554,QTextEdit
本身就很慢,现在没有希望在 Qt4 中修复它。
但是,错误报告评论确实显示了另一种执行查找和替换的方法,该方法可能会提供更好的性能。这是它的 PyQt4 端口:
def doReplaceAll(self):
...
self.editor.textCursor().beginEditBlock()
doc = self.editor.document()
cursor = QtGui.QTextCursor(doc)
while True:
cursor = doc.find(old, cursor, flags)
if cursor.isNull():
break
cursor.insertText(new)
self.editor.textCursor().endEditBlock()
在我的测试中,在 10k 行文件中进行大约 600 次替换或在 60k 行文件中进行大约 4000 次替换时,速度提高了 2-3 倍。不过总体表现还是很一般。
我正在开发一个文本编辑器我正在使用 Qt4.8/Pyqt 特别是 QTextedit 对象,在 Windows 7 上使用 python 2.7 考虑以下代码(非原创)
def doReplaceAll(self):
# Replace all occurences without interaction
# Here I am just getting the replacement data
# from my UI so it will be different for you
old=self.searchReplaceWidget.ui.text.text()
new=self.searchReplaceWidget.ui.replaceWith.text()
# Beginning of undo block
cursor=self.editor.textCursor()
cursor.beginEditBlock()
# Use flags for case match
flags=QtGui.QTextDocument.FindFlags()
if self.searchReplaceWidget.ui.matchCase.isChecked():
flags=flags|QtGui.QTextDocument.FindCaseSensitively
# Replace all we can
while True:
# self.editor is the QPlainTextEdit
r=self.editor.find(old,flags)
if r:
qc=self.editor.textCursor()
if qc.hasSelection():
qc.insertText(new)
else:
break
# Mark end of undo block
cursor.endEditBlock()
这适用于几百行文本。但是当我有很多文本时,说 10000 到 100000 行文本全部替换是非常慢的,以至于无法使用,因为编辑器的速度很快就会变慢。 难道我做错了什么。为什么 QTextEdit 这么慢,我尝试了 QplaingTextEdit 也没有太多运气。有什么建议吗?
如果不进行分析,您将很难准确找到减速的原因,但这可能与以下几个因素有关: PyQT 确实与其 C 库相关联,在两者之间处理数据可能会导致速度下降。
但请注意,您不仅在更改该代码中的文本,还在 text/window.
中重新定位光标我可以建议的最大加速是,如果您正在进行全局搜索和替换,请将所有文本拉入 python,使用 python 进行替换,然后重新插入:
def doReplaceAll(self):
# Replace all occurences without interaction
# Here I am just getting the replacement data
# from my UI so it will be different for you
old=self.searchReplaceWidget.ui.text.text()
new=self.searchReplaceWidget.ui.replaceWith.text()
# Beginning of undo block
cursor=self.editor.textCursor()
cursor.beginEditBlock()
text = self.editor.toPlainText()
text = text.replace(old,new)
self.editor.setPlainText(text)
# Mark end of undo block
cursor.endEditBlock()
根据 QTBUG-3554,QTextEdit
本身就很慢,现在没有希望在 Qt4 中修复它。
但是,错误报告评论确实显示了另一种执行查找和替换的方法,该方法可能会提供更好的性能。这是它的 PyQt4 端口:
def doReplaceAll(self):
...
self.editor.textCursor().beginEditBlock()
doc = self.editor.document()
cursor = QtGui.QTextCursor(doc)
while True:
cursor = doc.find(old, cursor, flags)
if cursor.isNull():
break
cursor.insertText(new)
self.editor.textCursor().endEditBlock()
在我的测试中,在 10k 行文件中进行大约 600 次替换或在 60k 行文件中进行大约 4000 次替换时,速度提高了 2-3 倍。不过总体表现还是很一般。