Если увеличить количество текста в списке texts, и изменять размер окна, начинаются лаги.
from sys import argv, exit from PySide6.QtCore import * from PySide6.QtGui import * from PySide6.QtWidgets import * from random import shuffle texts = ['Contented you dearest pleased happiness afraid use. Bachelor entirely vanity alone out travelling terms ' 'along. Otherwise open prepared prosperous weddings tastes. Cousin engage knew confined distrusts. Fifteen ' 'around adapted doubtful opinions ten boy introduced merits late those admire.', 'Attacks diminution if prosperous stand insensible too innate. Collected rapid share. Goodness concluded yet ' 'inhabiting lovers. Principles minutes disposing abode arranging. Answered result steepest promise ' 'remaining. '] class CustomSyntaxHighlighter(QSyntaxHighlighter): def __init__(self, document=None, parent=None): super().__init__(document) self.parent = parent self.index = [] self.format_letter = QTextCharFormat() self.format_letter.setForeground(QColor('red')) self.format_space = QTextCharFormat() self.format_space.setBackground(QColor('red')) def highlightBlock(self, text): text_bg = self.parent.textedit_bg.toPlainText().split('\n')[0] text_no_mistakes = '\n'.join(self.parent.practice_text[0:4]) text_entered = '' if len(text) <= len(text_bg): for i, t in enumerate(text_no_mistakes[:len(text)].strip('¶')): if t != text[i]: text_entered += text[i] self.setFormat(i, 1, self.format_space if text[i] == ' ' else self.format_letter) continue text_entered += t self.parent.textedit_bg.setText(text_entered + text_no_mistakes[len(text):]) class Window(QMainWindow): def __init__(self, parent=None): super(Window, self).__init__(parent) self.setWindowTitle('TextEdit') self.setMinimumSize(820, 0) self.centralwidget = QWidget(self) self.centralwidget.setObjectName(u"centralwidget") self.setCentralWidget(self.centralwidget) self.layout = QGridLayout(self.centralwidget) self.layout.setObjectName(u"layout") self.textedit_bg = QTextEdit(self) self.textedit_bg.setObjectName(u"textedit_bg") self.textedit_bg.setStyleSheet(''' #textedit_bg { background-color: #FF7F50; color: #FFFF00; font: 16pt "Cascadia Mono ExtraLight"; } ''') self.textedit_bg.setWordWrapMode(QTextOption.NoWrap) self.textedit = QTextEdit(self) # !!! lineedit self.textedit.setObjectName(u"textedit") self.textedit.setStyleSheet(''' #textedit { background-color: transparent; color: #0000CD; font: 16pt "Cascadia Mono ExtraLight"; } ''') self.textedit.setWordWrapMode(QTextOption.NoWrap) self.textedit.cursorPositionChanged.connect(self._change_cursor) self.textedit.selectionChanged.connect(self._change_selection) self.layout.addWidget(self.textedit_bg, 1, 1) self.layout.addWidget(self.textedit, 1, 1) self.button = QPushButton('Create Text', self) self.layout.addWidget(self.button, 2, 1) self.textedit_bg.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.textedit_bg.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.textedit.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.textedit.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.textedit_bg.setFixedHeight(132) self.textedit.setFixedHeight(132) self.textedit.setFocus() self.practice_text = '' self.text_width = 800 self.highlighter = CustomSyntaxHighlighter(self.textedit.document(), self) self.button.clicked.connect(lambda: self.get_text(True)) self.textedit.textChanged.connect(self.result) def result(self): text = self.textedit.toPlainText() text_bg = self.textedit_bg.toPlainText().split('\n')[0] if len(text) > len(text_bg.strip('¶')): if ('¶' in self.practice_text[0] and text[-1] != '\n' or text[-1] != ' ' and '¶' not in self.practice_text[0]): self.textedit.textCursor().deletePreviousChar() return del self.practice_text[0] self.get_text() return if text and len(text) != len(text_bg) and text[-1] in ('\n', '\t'): self.textedit.textCursor().deletePreviousChar() return def get_text(self, dev=False, resize=False): if dev and self.practice_text: del self.practice_text[0] if not self.practice_text: shuffle(texts) self.practice_text = self.capacity(texts) if resize and self.practice_text: self.practice_text = self.capacity(' '.join(self.practice_text).split('¶')[:-1]) if len(self.practice_text) <= 3: shuffle(texts) self.practice_text += self.capacity(texts) self.textedit_bg.setText('\n'.join(self.practice_text)) self.textedit.clear() self.textedit.setFocus() def capacity(self, text): result = [] for item in text: line = '' for w in item.split(): if self.text_width < self.__get_pixels_wide(line + w): result.append(line.strip()) line = '' line += w + ' ' result.append(line.strip() + '¶') return result def resizeEvent(self, event): if self.isVisible(): self.text_width = self.textedit.width() - 20 self.get_text(resize=True) def _change_cursor(self): cursor = self.textedit.textCursor() if cursor.positionInBlock() < len(self.textedit.document().toPlainText()): cursor.movePosition(QTextCursor.End) self.textedit.setTextCursor(cursor) def _change_selection(self): cursor = self.textedit.textCursor() cursor.clearSelection() self.textedit.setTextCursor(cursor) def __get_pixels_wide(self, words): return self.textedit_bg.fontMetrics().boundingRect(words).width() if __name__ == "__main__": app = QApplication(argv) window = Window() window.show() exit(app.exec())