Выделение строк в документе QTextEdit - PullRequest
1 голос
/ 09 февраля 2020

Попытка создать способ (используя PyQt5 и Python 3) выделить номер строки в документе виджета QTextEdit. Вот попытка кода ниже (большое спасибо тем в stackoverflow, которые ответили на подобные вопросы раньше):

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_())

Вопрос (ы):

  • Почему это так? нет необходимости создавать новый курсор для выбора всего документа (при сбросе выделения), но когда нужно выделить одну строку, нужно создать новый экземпляр QTextCursor ()?

  • Есть ли способ выделить одну строку без создания нового экземпляра?

  • При таком подходе возникнут проблемы с памятью, если документ длинный и необходимо выбрать большое количество строк?

Предположительно мусор Коллектор справился бы с этой проблемой, но я просто хотел узнать подробности за кулисами немного лучше.

1 Ответ

1 голос
/ 09 февраля 2020
  • Почему нет необходимости создавать новый курсор для выбора всего документа (при сбросе выделения), но когда требуется выделить одну строку, новый экземпляр QTextCursor ( ) нужно создавать?

    Поскольку выбор всего документа не требует наличия специальной информации в отличие от выбора строки, слова и т. Д. c. Так что любой QTextCursor, полученный из QTextEdit (точнее, любой QTextCursor из QTextDocument, связанного с QTextEdit) позволит вам выбрать весь документ.

  • Есть ли способ выбрать один линия без создания нового экземпляра?

    Для выбора строки необходимо, чтобы у QTextCursor была специальная информация, такая как начало и конец строки, поэтому вы должны построить QTextCursor на основе QTextBlock.

  • При таком подходе возникнут проблемы с памятью, если документ длинный и нужно выбрать большое количество строк?

    Нет, проблема с памятью не создается, поскольку в вашем случае вы назначаете ее тому же объекту, но я все еще предпочитаю использовать следующий метод

    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 - это локальные переменные, которые будут исключены после завершения выполнения метода.

...