【问题标题】:QTextedit find and replace performanceQTextedit 查找和替换性能
【发布时间】:2016-01-27 13:06:36
【问题描述】:

我正在开发一个文本编辑器我正在使用 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 也没有太多运气。有什么建议吗?

【问题讨论】:

  • 您可以尝试将文本作为纯字符串获取,然后在其中进行替换(可能还需要对其进行优化,以便每次替换不会一次又一次地移动字符串的其余部分......)。

标签: python-2.7 pyqt qt4 qtextedit


【解决方案1】:

根据QTBUG-3554 的说法,QTextEdit 本身就很慢,现在在 Qt4 中没有希望解决这个问题。

但是,错误报告 cmets 确实显示了另一种查找和替换的方法,它可能会提供更好的性能。这是它的 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 倍。不过,总体表现仍然相当平庸。

【讨论】:

  • 感谢您的回复好多了。至少我的小编辑器在做大量替换的时候是可以用的。接下来需要在选择中进行替换。谢谢
【解决方案2】:

如果不进行分析,您将很难准确找到减速的原因,但这可能与以下几个因素有关: PyQT 确实与其 C 库绑定,在两者之间处理数据可能会导致速度变慢。

但值得注意的是,您不仅要更改该代码中的文本,还要在文本/窗口中重新定位光标。

我可以建议的最大速度是,如果您要进行全局搜索和替换,请将所有文本拉入 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()

【讨论】:

    猜你喜欢
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 2010-11-16
    • 2014-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多