PyQt быстро обновляет QTextEdit как QAbstractItemModel - PullRequest
0 голосов
/ 15 февраля 2020

Есть ли способ создать модель для обновления QTextEdit, например, QAbstractItemModel.

В QAbstractItemModel / QAbstractTableModel есть метод data (index[, role=Qt.DisplayRole]), который вызывается всякий раз, когда представлению необходимо что-то отобразить. Это позволяет мне создать собственную структуру данных для быстрого сохранения данных в python. Есть ли способ заставить QTextEdit, QTextDocument или QTextDocumentLayout работать таким образом?

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

class QuickTextEdit(QtWidgets.QTextEdit):

    def update_display(self):
        for _ in range(len(self.queue)):
            text, fmt = self.queue.popleft()
            cursor = QtGui.QTextCursor(self.textCursor())
            cursor.beginEditBlock()

            # Move and check the position
            pos = cursor.position()
            cursor.movePosition(QtGui.QTextCursor.End)
            is_end = cursor.position() == pos

            # Insert the text
            cursor.setCharFormat(fmt)
            cursor.insertText(text)
            cursor.endEditBlock()

            # Move the cursor
            if is_end:
                # Actually move the text cursor
                cursor.movePosition(QtGui.QTextCursor.End)
                self.setTextCursor(cursor)

Я обнаружил, что это намного медленнее, чем работает QAbstractTableModel / QTableView.

Я бы хотел, чтобы виджет запрашивал данные (а не вставлял), как QAbstractItemModel. Я попытался использовать строку html в QLabel.paintEvent, но не смог заставить ее работать должным образом. Я действительно хотел бы просто HTML Просмотрщик текста для некоторой структуры данных / модели.

class QuickTextEdit(QtWidgets.QTextEdit):
    def data(self):
        return ''.join(('<font color="{color}">{text}</font>'.format(color=color, text=text)
                        for color, text in self.queue))

1 Ответ

0 голосов
/ 20 марта 2020

Вы можете реализовать простую настройку вида модели самостоятельно.

Вот некоторый псевдокод:

class TextEditView(QtWidgets.QTextEdit):
    def __init__(self, model):
        connect(model.dataChanged, self.update_display)

    @SLOT
    def update_display(self):
         text = model.data()
         self.setText(text)

class TextEditModel(QObject):
    SIGNAL dataChanged
    def data(self):
        new_text = queue.get_nowait()
        return new_text

class WorkerThread(QtCore.QThread):
    def run(self):
        queue.put(new_data)
        model.dataChanged.emit(index, index)

Тогда в вашем потоке вы сначала поместите новые данные в очередь. А затем подайте сигнал model.dataChanged. Затем представление будет опрашивать новые данные.

В качестве альтернативы вы можете пропустить все разделение представления модели и создать сигнал для TextEditView с нужным типом данных.

Дайте мне знать, как это происходит .

...