2
votes

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.

3

3 Answers

0
votes

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

0
votes

The problem is that you instatiate Ui_MainWindow twice: first as ex and later as ui. You connect the timer.timeout to ex, but call setupUi and show only for ui.

Try this:

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_())
-1
votes

Qt Designer is only used for designing the UI, it does not allow running the program. Qt Creator can run programs, but only "real" Qt C++ programs.

You need to launch your .py scripts outside of Qt Designer, as if it were a normal Python script.