Search code examples
pythonqtpyqt5qt-designer

Updating PyQt5 GUI with Live Data


I created a PyQt5 GUI using QtDesigner and converted it to Python. I was planning to update and display the value from the sensor reading from the Raspberry Pi. Since the GUI is in a loop, there is no way I can update data from outside that loop. Currently I used the code below where I use the QTimer widget that executes the function every given interval. Is this solution appropriate or not? What other methods are available to accomplish this task?

from PyQt5 import QtCore, QtGui, QtWidgets
from uimainwindow import Ui_MainWindow

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):

    numTest=0;

    def __init__(self):
        QtWidgets.QMainWindow.__init__(self)
        self.setupUi(self)
        QtCore.QTimer.singleShot(1000, self.getSensorValue)

    def getSensorValue(self):
        print(self.numTest)
        self.numTest=self.numTest+1
        QtCore.QTimer.singleShot(1000, self.getSensorValue)

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

Solution

  • To use a QTimer which calls a member function periodically:

    1. Make a member variable of QTimer.

    2. Set interval of QTimer to the intended delay.

    3. Connect getSensorValue() as signal handler to QTimer.timeout().

    4. Start QTimer member.

    Demo test-QTimer.py:

    #!/usr/bin/python3
    
    import sys
    from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel
    from PyQt5.QtCore import QTimer
    
    class MainWindow(QMainWindow):
      # constructor
      def __init__(self):
        QMainWindow.__init__(self)
        # counter
        self.i = 0
        # add QLabel
        self.qLbl = QLabel('Not yet initialized')
        self.setCentralWidget(self.qLbl)
        # make QTimer
        self.qTimer = QTimer()
        # set interval to 1 s
        self.qTimer.setInterval(1000) # 1000 ms = 1 s
        # connect timeout signal to signal handler
        self.qTimer.timeout.connect(self.getSensorValue)
        # start timer
        self.qTimer.start()
    
      def getSensorValue(self):
        self.i += 1
        # print('%d. call of getSensorValue()' % self.i)
        self.qLbl.setText('%d. call of getSensorValue()' % self.i)
    
    qApp = QApplication(sys.argv)
    # setup GUI
    qWin = MainWindow()
    qWin.show()
    # run application
    sys.exit(qApp.exec_())
    

    Tested in cygwin on Windows 10:

    Snapshot of test-QTimer.py