简体   繁体   中英

PyQt5 Unable to repaint QLabel's Text

I am trying to update the QLabel to reflect log changes but it will not repaint. I have tried multiple ways without success, a few are still listed in the code. The value of the log_text Label changes, it gets printed to terminal but never into the GUI. (The Grey Area is bound to the function to change the text)

import sys
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtGui import QPainter
from PyQt5.QtCore import QSize
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QHBoxLayout, QVBoxLayout, QDesktopWidget,
                             QLabel, QAbstractButton, QStackedWidget, QFrame, QTableWidget,)

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        self.center()

        self.setGeometry(500, 200, 1400, 800)

        layout1 = QHBoxLayout()
        layout2 = QVBoxLayout()
        layout3 = QVBoxLayout()
        layouts = QHBoxLayout()

        layout1.setSpacing(0)
        layout2.setSpacing(0)
        layout3.setSpacing(0)
        layouts.setSpacing(0)

        layout1.setContentsMargins(0, 0, 0, 0)
        layout2.setContentsMargins(0, 0, 0, 0)
        layout3.setContentsMargins(0, 0, 0, 0)
        layouts.setContentsMargins(0, 0, 0, 0)
        self.setContentsMargins(0, 0, 0, 0)

        widget = QWidget()
        widget.setLayout(layout1)
        self.setCentralWidget(widget)

        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)

        self.frameR = QFrame()
        self.frameR.setFrameShape(QFrame.StyledPanel)
        self.frameR.setStyleSheet("background-color: rgb(27, 29, 35); border: 0px solid black")
        self.frameR.setFixedWidth(71)
        self.frameR.setFixedHeight(71)
        layout2.addWidget(self.frameR)

        resize_layout = QVBoxLayout()
        self.frameR.setLayout(resize_layout)

        button5 = PicButtonF(QtGui.QPixmap("validationN.png"), QtGui.QPixmap("validationH.png"),
                             QtGui.QPixmap("validationC.png"))
        button5.clicked.connect(self.widget4)
        layout2.addWidget(button5)

        spacer_m = QFrame()
        spacer_m.setFrameShape(QFrame.StyledPanel)
        spacer_m.setStyleSheet("background-color: rgb(27, 29, 35); border: 0px solid black")
        spacer_m.setFixedWidth(71)
        layout2.addWidget(spacer_m)

        layout1.addLayout(layout2)

        label_title = QLabel("  PG - Programme De Gestion")
        label_title.setStyleSheet('background-color: rgb(37, 39, 44); color: white')
        layouts.addWidget(label_title)

        spacer_m = QFrame()
        spacer_m.setFrameShape(QFrame.StyledPanel)
        spacer_m.setStyleSheet("background-color: rgb(37, 39, 44); border: 0px solid black")
        spacer_m.setFixedHeight(45)
        layouts.addWidget(spacer_m)

        top3 = PicButtonF(QtGui.QPixmap("closeN.png"), QtGui.QPixmap("closeH.png"),
                          QtGui.QPixmap("closeH.png"))
        top3.clicked.connect(self.closeapp)
        top3.setFixedWidth(45)
        top3.setFixedHeight(45)
        layouts.addWidget(top3)

        layout3.addLayout(layouts)

        self.frameS = QFrame()
        self.frameS.setFrameShape(QFrame.StyledPanel)
        self.frameS.setStyleSheet("background-color: rgb(38, 41, 50); border: 0px solid black")
        self.frameS.setFixedHeight(24)
        layout3.addWidget(self.frameS)

        self.layoutS = QHBoxLayout()
        self.layoutS.setSpacing(0)
        self.layoutS.setContentsMargins(5, 5, 5, 5)
        self.frameS.setLayout(self.layoutS)

        self.log_text = QtWidgets.QLabel('Text That Must Change')
        self.log_text.setStyleSheet('color: white')
        self.layoutS.addWidget(self.log_text)

        self.stackedWidget = QStackedWidget()
        self.stackedWidget.addWidget(Validation())

        self.frameC = QFrame()
        self.layoutC = QHBoxLayout()
        self.frameC.setLayout(self.layoutC)
        self.layoutC.setSpacing(0)
        self.layoutC.setContentsMargins(0, 0, 0, 0)
        self.layoutC.addWidget(self.stackedWidget)
        layout3.addWidget(self.frameC)

        frame5 = QFrame()
        frame5.setFrameShape(QFrame.StyledPanel)
        frame5.setStyleSheet("background-color: rgb(37, 39, 44); border: 0px solid black")
        frame5.setFixedHeight(25)
        layout3.addWidget(frame5)

        credit_layout = QHBoxLayout()
        frame5.setLayout(credit_layout)

        layout1.addLayout(layout3)

        self.oldPos = self.pos()

    def logging(self, text):
        print(str('Testing - Text Passed Through Function: ') + str(text))
        print(str('Testing - Text Currently Before Function: ') + str(self.log_text.text()))
        self.log_text.setText(str('New Text From Logging Function'))
        self.log_text.hide()
        self.log_text.show()
        self.log_text.repaint()
        self.log_text.update()
        QtWidgets.qApp.processEvents()
        print(str('Testing - Text Set After Function: ') + str(self.log_text.text()))

    def widget4(self):
        self.stackedWidget.setCurrentIndex(4)

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def closeapp(self):
            self.close()

class Validation(QWidget):
    def __init__(self):
        super().__init__()

        self.header = ['CLIENT', 'TYPE']

        header_count = len(self.header)

        self.tableWidget = QTableWidget()
        self.tableWidget.setColumnCount(header_count)
        self.tableWidget.setRowCount(40)
        self.tableWidget.setHorizontalHeaderLabels(self.header)

        layout_tw = QVBoxLayout()
        layout_th = QHBoxLayout()

        frame1 = QFrame()
        frame1.setFrameShape(QFrame.StyledPanel)
        frame1.setStyleSheet("background-color: rgb(144, 149, 160); border: 0px solid black")
        frame1.setFixedHeight(50)
        frame1.setFixedWidth(122)

        frame1l = QHBoxLayout()
        frame1l.setSpacing(0)
        frame1l.setContentsMargins(5, 5, 5, 5)
        frame1.setLayout(frame1l)

        frame1b = PicButtonF(QtGui.QPixmap("query_all.png"), QtGui.QPixmap("query_all.png"),
                             QtGui.QPixmap("query_all.png"))
        frame1b.clicked.connect(self.validation_query)
        frame1l.addWidget(frame1b)

        frame_fill = QFrame()
        frame_fill.setFrameShape(QFrame.StyledPanel)
        frame_fill.setStyleSheet("background-color: rgb(44, 49, 60); border: 0px solid black")
        frame_fill.setFixedHeight(50)

        layout_th.addWidget(frame1)
        layout_th.addWidget(frame_fill)
        layout_tw.addLayout(layout_th)
        layout_tw.addWidget(self.tableWidget)

        layout_tw.setSpacing(0)
        layout_tw.setContentsMargins(0, 0, 0, 0)

        self.setLayout(layout_tw)

    def validation_query(self):
        MainWindow().logging('New Text From The Query Function')

class PicButtonF(QAbstractButton):
    def __init__(self, pixmap, pixmap_hover, pixmap_pressed, parent=None):
        super(PicButtonF, self).__init__(parent)
        self.pixmap = pixmap
        self.pixmap_hover = pixmap_hover
        self.pixmap_pressed = pixmap_pressed

    def paintEvent(self, event):
        pix = self.pixmap_hover if self.underMouse() else self.pixmap
        if self.isDown():
            pix = self.pixmap_pressed

        painter = QPainter(self)
        painter.drawPixmap(event.rect(), pix)

    def enterEvent(self, event):
        self.update()

    def leaveEvent(self, event):
        self.update()

    def sizeHint(self):
        return QSize(71, 71)

class PicButton(QAbstractButton):
    def __init__(self, pixmap, parent=None):
        super(PicButton, self).__init__(parent)
        self.pixmap = pixmap

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawPixmap(event.rect(), self.pixmap)

    def sizeHint(self):
        return self.pixmap.size()

def main():
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

You are not changing the label of the existing window, you are creating a new window everytime:

    def validation_query(self):
        .logging('New Text From The Query Function')

That line creates a new instance of MainWindow and calls that instance's logging function, then the new instance is immediately deleted (garbage collected) because no reference to it was ever created. Even if a reference (local or as an instance attribute) were created, that's clearly not the right approach.

To correctly change the label of the existing window, you should use a custom signal and connect it to the validation_query function. In order to do that you also cannot just add the widget to the stacked layout, as you need the reference to connect the new signal.

class MainWindow(QMainWindow):
    def __init__(self):
        # ...
        validator = Validation()
        self.stackedWidget.addWidget(validator)
        validator.validateResult.connect(self.logging)
        # ...
 
class Validation(QWidget):
    validateResult = QtCore.pyqtSignal(str)
    # ...
    def validation_query(self):
        self.validateResult.emit('New Text From The Query Function')

I recommend you to read more about classes and instances .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM