Search code examples
qtpython-2.7pyqtsignals-slots

Update the Style Sheet of a QTextEdit in QThread with pyqt


My GUI is composed of various groups of Qlabels and Qtext, which are updated by it's own QThread that is essentially state machine. My specs require that as the states change, each thread needs to update it's group of QLabels / QText, independently, with new text and change it's background color to red, yellow, or green. I'm having problems with the color change:

Code:

red_alert = "QText {Edit font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;bgcolor=red}"

class TesterThread(QtCore.QThread):
    updateText = QtCore.pyqtSignal(str)
    updateColor = QtCore.pyqtSignal(str)

    def __init__(self, thread_number, parent=None):
        super(TesterThread, self).__init__(parent)
        self.color = "red"
        self.status = "Disconnected"
        self.t_number = thread_number
        self.connection = False
        self.testing = False
        self.complete = False

    def run(self):
        self.tester()
    def tester(self, restart=False):
        if restart:
            logging.debug("Thread {}:Restarting for testing".format(self.t_number))
        else:
            logging.info("Thread {}:Ready for testing".format(self.t_number))
        # Init state, no device connected
        while not self.connection:
            self.updateText.emit("Status : {}".format(self.status))
            self.updateColor.emit("{}".format(thread_gui.red_alert))
            self.connection = True
            self.status = "Connected"
            self.updateText.emit("Status : {}".format(self.status))
            self.testing = True
        # Device connected, starting test
        while self.testing:
            self.status = "Testing"
            self.updateText.emit("Status : {}".format(self.status))
            self.testing = False
            self.complete = True
        # Test complete, waiting for unit removal
        while self.complete and self.connection:
            self.status = "Reset"
            self.updateText.emit("Status : {}".format(self.status))
            time.sleep(5)
            self.complete = False
            self.connection = False
            self.status = "Disconnected"
        # Unit remove, restart loop for next test.
        self.tester(restart=True)

GUI:

class TestSuiteGUI(QtGui.QMainWindow):
    def __init__(self, parent=None):
        self._threads = []
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.com_ports_list = serial_lib.get_com_ports()
        self.ui.setupUi(self)
        self.update_comm_fields(self.com_ports_list)
        logging.info("Spinning up threads...")
        for num, com_port_chunk in zip(range(1, 25), self.com_ports_list):
            tester_thread = TesterThread(thread_number=num)
            status_box = getattr(self.ui, 'status_{}'.format(num))
            tester_thread.updateText.connect(status_box.setText)
            status_box = getattr(self.ui, 'status_{}'.format(num))

            tester_thread.updateColor.connect(status_box.setStyleSheet)

            tester_thread.start()
            self._threads.append(tester_thread)

Solution

  • Your stylesheet doesn't look valid.

    QText {
        Edit font-family:'MS Shell Dlg 2'; 
        font-size:8.25pt; 
        font-weight:400; 
        font-style:normal;
        bgcolor=red
    }
    

    I'm guessing you want

    QTextEdit {
        font-family: "MS Shell Dlg 2"; 
        font-size: 8.25pt; 
        font-weight: 400; 
        font-style: normal;
        background-color: red;
    }
    

    When making stylesheet changes, it's useful to try them out first in Qt Designer to make sure they look the way you expect.