Search code examples
pythonmultithreadingpyqtpyqt4qlcdnumber

How to increment QLCDNumber in python


I am trying to update the value of a QLCDNumber. What I want to be able to do is run a function in a separate thread that outputs a value (in this case just counting upwards) and have this value displayed to the screen.

Here is the python script that I am using, and below that is the contents of the .ui file (where the QLCDNumber is named "disp"):

import sys
import threading
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import uic
from time import sleep


Ui_MainWindow, QtBaseClass = uic.loadUiType("./disp.ui")

class MainWindow(QMainWindow, Ui_MainWindow):
    counter = pyqtSignal(int)
    counting = False

    def __init__(self):
        QMainWindow.__init__(self)
        Ui_MainWindow.__init__(self)
        self.setupUi(self)

        self.disp.display(?????) #<---- 


    def startCounting(self):
        if not self.counting:
            self.counting = True
            thread = threading.Thread(target=self.something)
            thread.start()

    def something(self):
        for i in range(100):
            self.counter.emit(int(i))
            sleep(0.5)
        self.counting = False


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

.ui file:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>577</width>
    <height>504</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout">
    <item row="0" column="0">
     <widget class="QLCDNumber" name="disp"/>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>577</width>
     <height>24</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

Solution

  • You are almost there, you are emitting a signal with the new value however your signal is not connected to any function, you just need to create a function to update value of QLCDNumber and connect your signal counter to this function :

    import sys
    import threading
    
    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
    from PyQt4 import uic
    
    from time import sleep
    
    
    Ui_MainWindow, QtBaseClass = uic.loadUiType("./disp.ui")
    
    class MainWindow(QMainWindow, Ui_MainWindow):
        counter = pyqtSignal(int)
        counting = False
    
        def __init__(self):
            QMainWindow.__init__(self)
            Ui_MainWindow.__init__(self)
            self.setupUi(self)
    
            self.counter.connect(self.update_lcd)
            # self.startCounting()
    
        def update_lcd(self, value):
            self.disp.display(value)
    
        def startCounting(self):
            if not self.counting:
                self.counting = True
                thread = threading.Thread(target=self.something)
                thread.start()
    
        def something(self):
            for i in range(100):
                self.counter.emit(int(i))
                sleep(0.5)
            self.counting = False
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        window = MainWindow()
        window.show()
        sys.exit(app.exec_())
    

    I would suggest to use QThread or QRunnable instead of threading module to start your background task. A nice explanation of the difference can be found here.