如何动态更新 QSyntaxHighlighter 关键字

How to dynamically update QSyntaxHighlighter keywords

我正在制作一个文本编辑器 GUI,它允许动态突出显示用户输入的关键字。我正在使用 QSyntaxHighlighter 来突出显示在 QPlainTextEdit 框中找到的关键字。我能够在文本正文中找到子字符串以及每次出现的索引。但是格式没有正确应用。

荧光笔class:

class Highlighter(QSyntaxHighlighter):
    def __init__(self, parent):
        super().__init__(parent)

    def highlightBlock(self, text_block, kw):
        highlight_str = kw
        kw_format = QTextCharFormat()
        kw_format.setFontWeight(QFont.Bold)
        kw_format.setForeground(Qt.darkMagenta)
        for match in re.finditer(highlight_str, text_block):
            start, end = match.span()
            self.setFormat(start, end-start, kw_format)

接受用户输入并传递给荧光笔的突出显示文本函数:

    def highlight_text(self):
        input, pressed = QInputDialog.getText(self, "Highlight", "Enter keyword", QLineEdit.Normal, "")
        if pressed:
            highlight_str = str(input)
            highlighter = Highlighter(self)
            # rule for highlighting, can be expanded
            highlighter.highlightBlock(self.editor.document().toPlainText(), highlight_str)

我认为这不起作用,因为编辑器未 link 编辑到荧光笔?我如何 link 文本编辑器的荧光笔,但在用户输入新关键字后启用它重新评估文本正文?

来自关于 highlightBlock() 的文档(强调我的):

[...] This function is called when necessary by the rich text engine, i.e. on text blocks which have changed.

这意味着它不应以编程方式调用,但只要文档发生更改,文本引擎 (QTextDocument) 就会调用它。

然后必须使用 QPlainTextEdit 的 document() 作为参数创建荧光笔,它会自动启用。您应该为荧光笔保留一个参考,以便您可以在需要时更新或删除它:

    def highlight_text(self):
        input, pressed = QInputDialog.getText(self, "Highlight", 
            "Enter keyword", QLineEdit.Normal, "")
        if pressed:
            self.highlighter = Highlighter(self.document(), input)

    def resetHighlight(self):
        self.highlighter.setDocument(None)


class Highlighter(QSyntaxHighlighter):
    def __init__(self, document, searchString):
        super().__init__(document)
        self.searchString = searchString

    def highlightBlock(self, text):
        kw_format = QTextCharFormat()
        kw_format.setFontWeight(QFont.Bold)
        kw_format.setForeground(Qt.darkMagenta)
        for match in re.finditer(self.searchString, text):
            start, end = match.span()
            self.setFormat(start, end - start, kw_format)