ThomasH
ThomasH

Reputation: 77

PyQt5: Updating Label?

I'm currently having trouble updating labels continuously, I have tried my different ways but either nothing happens or the program stops working. I have attached below part of my code. Also I was hoping someone could explain exactly the purpose of def retranslateUi(self, MainWindow):

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("Tom")
        MainWindow.setWindowModality(QtCore.Qt.NonModal)
        MainWindow.resize(800, 600)
        MainWindow.setAutoFillBackground(False)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.Date = QtWidgets.QLabel(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(18)
        self.Date.setFont(font)
        self.Date.setAlignment(QtCore.Qt.AlignCenter)
        self.Date.setObjectName("Date")
        self.verticalLayout.addWidget(self.Date)
        self.Time = QtWidgets.QLabel(self.centralwidget)
        self.Time.setAlignment(QtCore.Qt.AlignCenter)
        self.Time.setObjectName("It is currently " + datetime.strptime(d, "%H:%M:%S").strftime( " %I:%M:%S %p"))
        self.verticalLayout.addWidget(self.Time)
        self.Weather = QtWidgets.QLabel(self.centralwidget)
        self.Weather.setAlignment(QtCore.Qt.AlignCenter)
        self.Weather.setWordWrap(False)
        self.Weather.setObjectName("Weather")
        self.verticalLayout.addWidget(self.Weather)
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.verticalLayout.addItem(spacerItem)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.verticalLayout.addItem(spacerItem1)
        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.verticalLayout.addItem(spacerItem2)
        spacerItem3 = QtWidgets.QSpacerItem(771, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.verticalLayout.addItem(spacerItem3)
        spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.verticalLayout.addItem(spacerItem4)
        spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.verticalLayout.addItem(spacerItem5)
        MainWindow.setCentralWidget(self.centralwidget)

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


    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("Tom", "Tom"))
        self.Date.setText(_translate("Tom", "Today is " + week_day +" the " + (ordinal(day)) + " of " + (month)))
        self.Time.setText(_translate("Tom", "It is currently " + datetime.strptime(d, "%H:%M:%S").strftime( " %I:%M:%S %p")))
        self.Weather.setText(_translate("Tom", "New York City " + str(ctemp) + "\xb0F " + string.capwords(status)))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

I want the label that gets the current time to keep updating and the call to weather api to happen about every 5 min. Any help is greatly appreciated!

Upvotes: 4

Views: 5771

Answers (2)

eyllanesc
eyllanesc

Reputation: 244282

To implement the code we will do the following:

  1. To update the time we use a timer.
  2. To obtain the weather data, we use the pyowm library.
  3. The task of obtaining the weather can block the main thread of the GUI, therefore we will create a Thread.
  4. Within the thread we will create a signal that will store the weather information and connect it to the main thread via the updateTemp slot.

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent=parent)
        self.setupUi(self)
        timerTime = QtCore.QTimer(self)
        timerTime.timeout.connect(self.updateDate)
        timerTime.start(1000)
        self.pyowm = PyownThread(self)
        self.pyowm.tempSignal.connect(self.updateTemp)
        self.pyowm.start()

    def updateDate(self):
        date = QtCore.QDateTime.currentDateTime()
        self.Date.setText("Today is " + date.toString("ddd MMMM d yyyy"))
        self.Time.setText("It is currently " + date.toString("hh:mm:ss ap"))

    def updateTemp(self, temp):
        self.Weather.setText("New York City temperature:" + str(temp['temp']) + " \u00B0C")

Thread:

class PyownThread(QtCore.QThread):
    tempSignal = QtCore.pyqtSignal(dict)
    def __init__(self, parent=None):
        super(PyownThread, self).__init__(parent=parent)
        self.owm = pyowm.OWM('1589dbcc0e9608e5b70f0ede23e757c8')


    def run(self):
        while True:
            observation = self.owm.weather_at_place('New York,us')
            w = observation.get_weather()
            ctemp = w.get_temperature('celsius')
            self.tempSignal.emit(ctemp)
            self.sleep(5*60)

About the question: could explain exactly the purpose of def retranslateUi(self, MainWindow)?

This serves to make translatable into several languages, for example the same code could be used for an audience that speaks English, Spanish, German, etc. For your purposes it is not necessary.

Complete code:

from PyQt5 import QtWidgets, QtGui, QtCore
import pyowm


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("Tom")
        MainWindow.setWindowModality(QtCore.Qt.NonModal)
        MainWindow.resize(800, 600)
        MainWindow.setAutoFillBackground(False)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.Date = QtWidgets.QLabel(self.centralwidget)
        font = QtGui.QFont()
        font.setPointSize(18)
        self.Date.setFont(font)
        self.Date.setAlignment(QtCore.Qt.AlignCenter)
        self.Date.setObjectName("Date")
        self.verticalLayout.addWidget(self.Date)
        self.Time = QtWidgets.QLabel(self.centralwidget)

        self.verticalLayout.addWidget(self.Time)
        self.Weather = QtWidgets.QLabel(self.centralwidget)
        self.Weather.setAlignment(QtCore.Qt.AlignCenter)
        self.Weather.setWordWrap(False)
        self.Weather.setObjectName("Weather")
        self.verticalLayout.addWidget(self.Weather)
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.verticalLayout.addItem(spacerItem)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.verticalLayout.addItem(spacerItem1)
        spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.verticalLayout.addItem(spacerItem2)
        spacerItem3 = QtWidgets.QSpacerItem(771, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.verticalLayout.addItem(spacerItem3)
        spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.verticalLayout.addItem(spacerItem4)
        spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.verticalLayout.addItem(spacerItem5)
        MainWindow.setCentralWidget(self.centralwidget)

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


    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("Tom", "Tom"))
        self.Date.setText(_translate("Tom", "Today is "))
        self.Time.setText(_translate("Tom", "It is currently "))
        self.Weather.setText(_translate("Tom", "New York City" ))


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent=parent)
        self.setupUi(self)
        timerTime = QtCore.QTimer(self)
        timerTime.timeout.connect(self.updateDate)
        timerTime.start(1000)
        self.pyowm = PyownThread(self)
        self.pyowm.tempSignal.connect(self.updateTemp)
        self.pyowm.start()

    def updateDate(self):
        date = QtCore.QDateTime.currentDateTime()
        self.Date.setText("Today is " + date.toString("ddd MMMM d yyyy"))
        self.Time.setText("It is currently " + date.toString("hh:mm:ss ap"))

    def updateTemp(self, temp):
        self.Weather.setText("New York City temperature:" + str(temp['temp']) + " \u00B0C")


class PyownThread(QtCore.QThread):
    tempSignal = QtCore.pyqtSignal(dict)
    def __init__(self, parent=None):
        super(PyownThread, self).__init__(parent=parent)
        self.owm = pyowm.OWM('1589dbcc0e9608e5b70f0ede23e757c8') 

    def run(self):
        while True:
            observation = self.owm.weather_at_place('New York,us')
            w = observation.get_weather()
            ctemp = w.get_temperature('celsius')
            self.tempSignal.emit(ctemp)
            QtCore.QThread.sleep(5*60)



if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

enter image description here

Upvotes: 5

Luchko
Luchko

Reputation: 1153

Here is a small working example that should help you. QTimer is used for periodical calling the update_labelTime function.

import sys
from PyQt5.QtCore import QTimer, QTime
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel

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

        self.labelTime = QLabel()
        self.update_labelTime()
        self.setCentralWidget(self.labelTime)

        self.timer = QTimer()
        self.timer.timeout.connect(self.update_labelTime)
        self.timer.start(1000) # repeat self.update_labelTime every 1 sec

    def update_labelTime(self):

        time_str = "Current time: {0}".format(QTime.currentTime().toString())
        self.labelTime.setText(time_str)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())

P.S. Don't forget to change the updating period in timer.start call

Upvotes: 2

Related Questions