QTextEdit 文档上的高亮行

Highlighting lines on QTextEdit document

正在尝试创建一种方法(使用 PyQt5 和 Python 3)来突出显示 QTextEdit 小部件文档中的给定行号。这是下面尝试的代码(非常感谢之前回答过类似问题的Whosebug中的那些人):

from PyQt5.QtCore import Qt, QTimer, QEventLoop
from PyQt5.QtGui import QTextBlockFormat, QTextBlock, QTextCursor
from PyQt5.QtWidgets import QWidget, QApplication, QTextEdit, QVBoxLayout

sample = """
Test document...
This is Line 2
This is Line 3
Explanation:
  This is an explanation section. Here we explain.
  Explanation section ends.
Back to body of document.
This is Line 8.
This is the last line.
"""


class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.editor = QTextEdit(self)
        self.editor.setText(sample)

        self.format_normal = QTextBlockFormat()
        self.format_normal.setBackground(Qt.white)

        self.highlight_format = QTextBlockFormat()
        self.highlight_format.setBackground(Qt.yellow)

        self.cursor = self.editor.textCursor()

        layout = QVBoxLayout(self)
        layout.addWidget(self.editor)

    def setLineFormat(self, lineNumber, format):
        """ Sets the highlighting of a given line number in the QTextEdit"""
        #self.cursor.clearSelection()
        self.cursor.select(QTextCursor.Document)
        self.cursor.setBlockFormat(self.format_normal)

        self.cursor = QTextCursor(self.editor.document().findBlockByNumber(lineNumber))
        self.cursor.setBlockFormat(format)

    def cycle_through_lines(self):
        """ Cycles through specified lines. """
        for ii in range(2, 8):
            self.setLineFormat(ii, self.highlight_format)
            self.pause(1000)

    def pause(self, duration):
        """ Provides a pause of a specified duration. """
        loop = QEventLoop()
        QTimer.singleShot(duration, loop.quit)
        loop.exec_()


if __name__ == '__main__':

    import sys
    app = QApplication(sys.argv)
    window = Window()
    window.setGeometry(500, 150, 300, 300)
    window.show()
    window.cycle_through_lines()
    sys.exit(app.exec_())

问题:

大概垃圾收集器会处理这个问题,但我只是想更好地了解幕后的细节。

  • 为什么不需要实例化一个新游标到select整个文档(重置高亮时),但是当需要单行时selected,需要创建 QTextCursor() 的新实例吗?

    因为 select 编辑整个文档不需要特殊信息,不像 select 编辑一行,单词等。所以从 QTextEdit 获得的任何 QTextCursor(更准确地说是QTextDocument 与 QTextEdit 相关联)将允许您 select 整个文档。

  • 有没有办法在不创建新实例的情况下 select 单行?

    到select需要一行,QTextCursor有行首行尾等特殊信息,所以必须基于QTextBlock构建一个QTextCursor。

  • 如果文档很长并且需要编辑大量行,这种方法会产生任何内存问题吗?

    不,不会产生内存问题,因为在你的情况下你将它分配给同一个对象,但我仍然更喜欢使用以下方法

    def setLineFormat(self, lineNumber, format):
        """ Sets the highlighting of a given line number in the QTextEdit"""
        cursor = self.editor.textCursor()
        cursor.select(QTextCursor.Document)
        cursor.setBlockFormat(self.format_normal)</p>
    
        cursor = QTextCursor(self.editor.document().findBlockByNumber(lineNumber))
        cursor.setBlockFormat(format)
    

    在我的方法中,QTextCursor 是局部变量,当方法执行完毕时将被消除。