потоковое обновление html данных в окне pyqt5

Есть программка, которая в отдельном потоке постоянно обновляет данные в label.

Хочу сделать так чтобы эти данные были цветными. Но при попытке отправить html текст на окно, программа дропается (windows считает что программа свое отработала и предлагает её закрыть). Попытки отловить ошибку к успеху не привели.

Для примера:

import sys

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

class Trd(QThread):
    def __init__(self, parent, function):
        super(Trd, self).__init__(parent)
        self.function = function
    def run(self):self.function()

class Win(QMainWindow):
    def __init__(self):
        super(Win, self).__init__()
        self.setGeometry(100, 100, 300, 100)

        self.label = QLabel(self)
        self.label.setGeometry(0, 0, 100, 100)
        self.label.setText('TEXT')

        self.show()

        trd = Trd(self, self.update_label)
        trd.start()

    def update_label(self):
        lines = ['<font color="red">RED</font>',
                 '<font color="blue">BLUE</font>',
                 '<font color="green">GREEN</font>']
        # lines = ['RED',
        #          'BLUE',
        #          'GREEN']

        while True:
            for i in range(len(lines)):
                self.label.setText(lines[i])
                QThread.sleep(1)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    application = Win()
    sys.exit(app.exec_())

Если использовать код в комментарии - программа не дропнется и будет работать. В гугле не нашел информации по этому поводу. Намекните мне, что я делаю не так?


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

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

Нельзя использовать объекты основного потока в дополнительных потоках, это не безопасно! Надо использовать сигналы и слоты, примерно так:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *


class Trd(QThread):
    newColorSignal = pyqtSignal(str)
    
    def __init__(self, parent): 
        super(Trd, self).__init__(parent)
        self.lines = ['<font color="red">RED</font>',
                 '<font color="blue">BLUE</font>',
                 '<font color="green">GREEN</font>']
        
    def run(self):
        i = 0
        while True:
            self.newColorSignal.emit(self.lines[i])
            i = i + 1 if i < 2 else 0
            self.sleep(1)
        

class Win(QMainWindow):
    def __init__(self):
        super(Win, self).__init__()
        self.setGeometry(100, 100, 300, 100)

        self.label = QLabel(self)
        self.label.setGeometry(0, 0, 100, 100)
        self.label.setText('TEXT')

        self.show()

        self.trd = Trd(self) #, self.update_label)
        self.trd.newColorSignal.connect(self.update_label)
        self.trd.start()

    def update_label(self, text):
        self.label.setText(text)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setFont(QFont("Times", 16, QFont.Bold))
    application = Win()
    sys.exit(app.exec_())

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

→ Ссылка