Как покрасить разные буквы надписи QLabel в разные цвета PyQt5

Пишу приложение, измеряющее вашу скорость печати.

Столкнулся с проблемой: не могу выделять правильно написанные буквы зеленым цветом, а ошибочно написанные красным.

Как я могу в одной надписи текст писать двумя разными цветами?
(Желательно, чтобы это работало с помощью индексов)

from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys, random, time
from PyQt5.Qt import *
from PyQt5 import QtWidgets
from PyQt5.QtTest import *

class Window(QWidget):
    def __init__(self, parent = None):
        QWidget.__init__(self, parent)


        self.text_for_typing = QLabel(self)
        self.text_for_typing.setGeometry(140,100,320,150)
        self.text_for_typing.setStyleSheet("background-color: rgb(255, 255, 127); \
                                            font: 87 14pt Segoe UI Black;")
        self.text_for_typing.setWordWrap(True)

        self.time = QLabel(self)
        self.time.setGeometry(120,400,100,25)
        self.time.setStyleSheet("font: 18pt Snap ITC;")

        self.button_generate_symbols = QPushButton(self)
        self.button_generate_symbols.setGeometry(20, 145, 90, 30)
        self.button_generate_symbols.setText("Generate")
        self.button_generate_symbols.setStyleSheet("background-color: rgb(85, 85, 127); \
                                                          font: 87 11pt Segoe UI Black;")

        self.button_start = QPushButton(self)
        self.button_start.setGeometry(490, 100, 90, 30)
        self.button_start.setText("Start")
        self.button_start.setStyleSheet("background-color: rgb(85, 85, 127); \
                                                                  font: 87 11pt Segoe UI Black;")

        self.letters = "абвгдежзиклмнопрстуфхцчшщйэюя "
        self.numbers = "0123456789"

        self.area_for_typing = QTextEdit(self)
        self.area_for_typing.setGeometry(140,280,320,50)
        self.area_for_typing.setStyleSheet("font: 87 11pt Segoe UI Black;")



        self.button_text_or_numbers = QPushButton(self)
        self.button_text_or_numbers.setGeometry(20,100,90,30)
        self.button_text_or_numbers.setText("Text")
        self.button_text_or_numbers.setStyleSheet("background-color: rgb(85, 85, 127); \
                                                  font: 87 11pt Segoe UI Black;")

        self.main_name = QLabel(self)
        self.main_name.setGeometry(140,30,320,50)
        self.main_name.setText("TypingSpeed")
        self.main_name.setStyleSheet("font: 36pt Algerian;")

        self.setStyleSheet("background-color: rgb(170, 170, 255);")
        self.setWindowTitle("TypingSpeed")
        self.setWindowIcon(QIcon("keyboard.ico"))
        self.resize(600,450)
        self.setFixedSize(self.size())

        self.show()

    def action(self):

        self.button_text_or_numbers.clicked.connect(self.change_text_or_numbers)
        self.button_generate_symbols.clicked.connect(self.generate_symbols)
        self.button_start.clicked.connect(self.start)

    def change_text_or_numbers(self):
        if self.button_text_or_numbers.text() == "Text":
            self.button_text_or_numbers.setText("Numbers")
            self.text_for_typing.setText("")
        else:
            self.button_text_or_numbers.setText("Text")
            self.text_for_typing.setText("")

    def generate_symbols(self):
        text_for_typing = ""

        if self.button_text_or_numbers.text() == "Text":
            strings = []

            file = open("ENRUS.TXT")
            file.seek(0)

            for line in file:
                if line[0] in self.letters and line[0:-1] not in self.numbers:
                    strings.append(line)

            for i in range(6):
                random_int = random.randint(0,100)
                word = strings[random_int]
                text_for_typing+= word + " "

            self.text_for_typing.setText(f"<center>{text_for_typing}</center>")

        else:
            for i in range(20):
                number = ""

                for j in range(4):
                    number+=self.numbers[random.randint(0,len(self.numbers)-1)]

                text_for_typing += number + " "

            self.text_for_typing.setText(f"<center>{text_for_typing}</center>")

    def start(self):
        if self.text_for_typing.text() != "":
            seconds = [3, 2, 1]
            self.button_text_or_numbers.setEnabled(False)
            self.button_generate_symbols.setEnabled(False)
            self.button_start.setStyleSheet("background-color: rgb(255,85,0); \
                                             font: 87 11pt Segoe UI Black;")
            
            for i in range(3):
                self.button_start.setEnabled(False)
                self.button_start.setText(f"{seconds[i]}")
                qApp.processEvents()
                time.sleep(1)
                
            self.button_start.setEnabled(True)
            self.button_start.setText("Finish")
            seconds = 0
            
            while True:
                if self.text_for_typing.text()[8:len(self.area_for_typing.toPlainText())+8] == self.area_for_typing.toPlainText():
                    self.text_for_typing.setStyle() #Вот здесь буду пытаться красить правильные буквы (8: И +8, т.к. <center> в self.text_for_typing
                    
                QTest.qWait(1000)
                seconds+=1
                self.time.setText(f"{seconds}s")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.action()
    sys.exit(app.exec_())

Ответы (1 шт):

Автор решения: S. Nick

То, что вы задумали, может выглядеть примерно так:

import sys
from PyQt5.Qt import *


class Window(QWidget):
    def __init__(self, parent = None):
        QWidget.__init__(self, parent)
        
        self.textEdit = QTextEdit(self)
        self.text = "Hello World 12345"
        self.textEdit.setText(self.text) 
        self.textEdit.setGeometry(140, 100, 320, 150)
        self.textEdit.setStyleSheet("""
            background-color: rgb(255, 255, 127);
            font: 87 14pt Segoe UI Black;
        """)
        self.textEdit.setFocusPolicy(Qt.NoFocus)

        # Установите желаемый формат 
        # Класс QTextCharFormat предоставляет информацию о форматировании символов в QTextDocument.
        self.format = QTextCharFormat()
        self.format.setFont(QFont("Times", 12, QFont.Bold)) 

        self.area_for_typing = QTextEdit(self)
        self.area_for_typing.setGeometry(140, 280, 320, 50)
        self.area_for_typing.setStyleSheet("font: 87 11pt Segoe UI Black;")
        self.area_for_typing.document().contentsChange.connect(self.contents_change)
        self.area_for_typing.setFixedHeight(70)
        self.area_for_typing.setEnabled(False)

        self.timeLabel = QLabel()
        
        self.button_start = QPushButton("Start") 
        self.button_start.clicked.connect(self.start)
        
        layout = QVBoxLayout(self)
        layout.addWidget(self.textEdit)
        layout.addWidget(self.area_for_typing)
        layout.addWidget(self.timeLabel)
        layout.addWidget(self.button_start)
        
        self.timer = QTimer()
        self.timer.timeout.connect(self.updateTime)
        self.second = 0

    def updateTime(self): 
        self.second += 1
        self.timeLabel.setText(f'{self.second} s')
        
    def start(self):
        self.textEdit.setText(self.text)
        self.area_for_typing.clear()
        self.timeLabel.clear()
        self.area_for_typing.setEnabled(True)
        self.area_for_typing.setFocus()
        self.second = 0
        self.timer.start(1000)

    def contents_change(self, position, charsRemoved, charsAdded):
        if not self.area_for_typing.document().toPlainText():
            return
       
        cursor = self.textEdit.textCursor()
        cursor.setPosition(position)
        end = cursor.movePosition(QTextCursor.NextCharacter, 1)
        
        if end:
            letter_text = self.text[position]
            letter_area_for_typing = self.area_for_typing.document().toPlainText()[position]
            if letter_text == letter_area_for_typing:
                self.format.setTextOutline(QPen(QColor("green")))
            else:
                self.format.setTextOutline(QPen(QColor("red")))

            if position == len(self.text)-1:
                self.area_for_typing.setEnabled(False)
                self.timer.stop()                
        else:
            self.area_for_typing.setEnabled(False)
            self.timer.stop()
        
        cursor.mergeCharFormat(self.format)

       
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.resize(400, 300)
    window.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка