Search code examples
pythonpyqtpyqt5qt-designerqlabel

Change QLabel text dynamically not working


I am trying to change the QLabel text dymanically using QtDesigner, pyqt5.

Below is the code i am trying to use for changing the QLabel text dymanically.

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

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setObjectName("label")
        self.horizontalLayout.addWidget(self.label, 0, QtCore.Qt.AlignHCenter)
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" font-size:28pt;\">" + self.getTime() + "</span></p></body></html>"))

    def getTime(self):
        time = QTime.currentTime().toString()
        return time

    def data(self):
        time = QTime.currentTime().toString()
        print("Time: " + time)
        self.label.setText(time)
        return time

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()

    ex = Ui_MainWindow()
    timer = QtCore.QTimer()
    timer.timeout.connect(ex.data)
    timer.start(1000) # 1 Second Refesh Rate

    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

When i tried to run the code in QtDesigner the output window open's for a second and closed automatically. Not sure what is causing the output window to close. Please advise me to resolve the issue.


Solution

  • I recommend you execute your code in the terminal/CMD since many IDEs do not handle the Qt errors, if you do it you would get the following error:

    Traceback (most recent call last):
      File "main.py", line 33, in data
        self.label.setText(time)
    AttributeError: 'Ui_MainWindow' object has no attribute 'label
    

    The error indicates that label does not exist, and that is correct because label is created after calling setupUi() but in your case "ex" does not call it. A possible solution is to first create the window and then start the timer:

    if __name__ == "__main__":
        import sys
        app = QtWidgets.QApplication(sys.argv)
        MainWindow = QtWidgets.QMainWindow()
        ui = Ui_MainWindow()
        ui.setupUi(MainWindow)
        MainWindow.show()
        timer = QtCore.QTimer()
        timer.timeout.connect(ui.data)
        timer.start(1000) # 1 Second Refesh Rate
        sys.exit(app.exec_())
    

    But a better solution is to follow the recommendations of PyQt(1) that states that you should not modify the class provided by Qt but use it as the widget interface:

    from PyQt5 import QtCore, QtGui, QtWidgets
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    
    
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            MainWindow.setObjectName("MainWindow")
            MainWindow.resize(800, 600)
            self.centralwidget = QtWidgets.QWidget(MainWindow)
            self.centralwidget.setObjectName("centralwidget")
            self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
            self.horizontalLayout.setObjectName("horizontalLayout")
            self.label = QtWidgets.QLabel(self.centralwidget)
            self.label.setObjectName("label")
            self.horizontalLayout.addWidget(self.label, 0, QtCore.Qt.AlignHCenter)
            MainWindow.setCentralWidget(self.centralwidget)
    
            self.retranslateUi(MainWindow)
            QtCore.QMetaObject.connectSlotsByName(MainWindow)
    
        def retranslateUi(self, MainWindow):
            _translate = QtCore.QCoreApplication.translate
            MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
            self.label.setText(
                _translate(
                    "MainWindow",
                    '<html><head/><body><p><span style=" font-size:28pt;"></span></p></body></html>',
                )
            )
    
    
    class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            self.setupUi(self)
            timer = QtCore.QTimer(self)
            timer.timeout.connect(self.data)
            timer.start(1000)
            self.data()
    
        def data(self):
            time_str = QTime.currentTime().toString()
            self.label.setText(
                '<html><head/><body><p><span style=" font-size:28pt;">{}</span></p></body></html>'.format(
                    time_str
                )
            )
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        w = MainWindow()
        w.show()
        sys.exit(app.exec_())
    

    (1) Using the Generated Code