【问题标题】:How can I find a substring and highlight it in QTextEdit?如何在 QTextEdit 中找到子字符串并突出显示它?
【发布时间】:2012-12-08 13:01:50
【问题描述】:

我有一个显示文件内容的 QTextEdit 窗口。 我希望能够使用正则表达式在文本中找到所有匹配项,并通过使匹配背景不同或通过更改匹配文本颜色或使其变为粗体来突出显示它们。我该怎么做?

【问题讨论】:

  • QTextEdit 接受 html 标签,您可以使用正则表达式将匹配的文本与标签包装起来
  • @X.Jacobs,请对主要是粗体文本的建议编辑放轻松。这并没有真正增加任何问题。访问元discussion on the topic
  • 发生了一些事情,您的帖子有几个重叠的编辑,对此感到抱歉,我建议您查看How to Ask

标签: python regex qt pyqt pyside


【解决方案1】:

QT5 更新了 RegEx,见 QRegularExpression https://dangelog.wordpress.com/2012/04/07/qregularexpression/

我已经使用游标更新了第一个示例。

注意以下变化:

  1. 这不会包装编辑,而是使用里面的编辑框,可以很容易地更改它以允许您传入编辑小部件。

  2. 这会进行正确的正则表达式查找,而不仅仅是一个单词。

    def do_find_highlight(self, pattern):
        cursor = self.editor.textCursor()
        # Setup the desired format for matches
        format = QTextCharFormat()
        format.setBackground(QBrush(QColor("red")))
        
        # Setup the regex engine
        re = QRegularExpression(pattern)
        i = re.globalMatch(self.editor.toPlainText()) # QRegularExpressionMatchIterator

        # iterate through all the matches and highlight
        while i.hasNext():
            match = i.next() #QRegularExpressionMatch

            # Select the matched text and apply the desired format
            cursor.setPosition(match.capturedStart(), QTextCursor.MoveAnchor)
            cursor.setPosition(match.capturedEnd(), QTextCursor.KeepAnchor)
            cursor.mergeCharFormat(format)

【讨论】:

    【解决方案2】:

    我认为解决问题的最简单方法是使用与编辑器关联的光标来进行格式化。这样您就可以设置前景、背景、字体样式...以下示例将匹配项标记为不同的背景。

    from PyQt4 import QtGui
    from PyQt4 import QtCore
    
    class MyHighlighter(QtGui.QTextEdit):
        def __init__(self, parent=None):
            super(MyHighlighter, self).__init__(parent)
            # Setup the text editor
            text = """In this text I want to highlight this word and only this word.\n""" +\
            """Any other word shouldn't be highlighted"""
            self.setText(text)
            cursor = self.textCursor()
            # Setup the desired format for matches
            format = QtGui.QTextCharFormat()
            format.setBackground(QtGui.QBrush(QtGui.QColor("red")))
            # Setup the regex engine
            pattern = "word"
            regex = QtCore.QRegExp(pattern)
            # Process the displayed document
            pos = 0
            index = regex.indexIn(self.toPlainText(), pos)
            while (index != -1):
                # Select the matched text and apply the desired format
                cursor.setPosition(index)
                cursor.movePosition(QtGui.QTextCursor.EndOfWord, 1)
                cursor.mergeCharFormat(format)
                # Move to the next match
                pos = index + regex.matchedLength()
                index = regex.indexIn(self.toPlainText(), pos)
    
    if __name__ == "__main__":
        import sys
        a = QtGui.QApplication(sys.argv)
        t = MyHighlighter()
        t.show()
        sys.exit(a.exec_())
    

    代码是不言自明的,但如果您有任何问题,请直接问他们。

    【讨论】:

    • 太棒了!那行得通!现在我必须了解那里发生了什么;)
    • 我最近发现了一个问题,有时大文本在 QTextEdit 窗口中显示时会被截断。我能够将其缩小到 cursor.mergeCharFormat(format) 行。如果我将其注释掉并且不应用格式,它会显示完整的文件就好了。有什么办法可以解决这个问题吗?
    • @EugeneSajine 抱歉,我无法重现该错误。您能否将文本提供给我(通过pastebin 或类似方式),以便我看到失败?谢谢。
    【解决方案3】:

    以下是如何突出显示 QTextEdit 中的文本的示例:

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    
    from PyQt4.QtGui import *
    from PyQt4.QtCore import *
    
    class highlightSyntax(QSyntaxHighlighter):
        def __init__(self, listKeywords, parent=None):
            super(highlightSyntax, self).__init__(parent)
            brush   = QBrush(Qt.darkBlue, Qt.SolidPattern)
            keyword = QTextCharFormat()
            keyword.setForeground(brush)
            keyword.setFontWeight(QFont.Bold)
    
            self.highlightingRules = [  highlightRule(QRegExp("\\b" + key + "\\b"), keyword)
                                        for key in listKeywords
                                        ]
    
        def highlightBlock(self, text):
            for rule in self.highlightingRules:
                expression = QRegExp(rule.pattern)
                index      = expression.indexIn(text)
    
                while index >= 0:
                  length = expression.matchedLength()
                  self.setFormat(index, length, rule.format)
                  index = text.indexOf(expression, index + length)
    
            self.setCurrentBlockState(0)  
    
    class highlightRule(object):
        def __init__(self, pattern, format):
            self.pattern = pattern
            self.format  = format
    
    class highlightTextEdit(QTextEdit):
        def __init__(self, fileInput, listKeywords, parent=None):
            super(highlightTextEdit, self).__init__(parent)
            highlightSyntax(QStringList(listKeywords), self)
    
            with open(fileInput, "r") as fInput:
                self.setPlainText(fInput.read())        
    
    if __name__ == "__main__":
        import  sys
    
        app = QApplication(sys.argv)
        main = highlightTextEdit("/path/to/file", ["foo", "bar", "baz"])
        main.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 感谢您的意见!我选择了 Vicent 的答案,因为它是一个更简单的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    • 2013-10-21
    • 2015-06-24
    • 1970-01-01
    • 2021-12-15
    相关资源
    最近更新 更多