QT4 Progressbar


In this article we will demonstrate how to use the progressbar widget.  The progressbar is different from the other widgets in that it updates in time.  Let’s start with the code:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4.QtCore import pyqtSlot,SIGNAL,SLOT
 
class QProgBar(QProgressBar):
 
    value = 0
 
    @pyqtSlot()
    def increaseValue(progressBar):
        progressBar.setValue(progressBar.value)
        progressBar.value = progressBar.value+1
 
# Create an PyQT4 application object.
a = QApplication(sys.argv)       
 
# The QWidget widget is the base class of all user interface objects in PyQt4.
w = QWidget()
 
# Set window size. 
w.resize(320, 240)
 
# Set window title  
w.setWindowTitle("PyQT4 Progressbar @ pythonspot.com ") 
 
# Create progressBar. 
bar = QProgBar(w)
bar.resize(320,50)    
bar.setValue(0)
bar.move(0,20)
 
# create timer for progressBar
timer = QTimer()
bar.connect(timer,SIGNAL("timeout()"),bar,SLOT("increaseValue()"))
timer.start(400) 
 
# Show window
w.show() 
 
sys.exit(a.exec_())

The instance bar (of class QProgBar) is used to hold the value of the progressbar.  We call the function setValue() to update its value.  The parameter w is given to attach it to the main window. We then move it to position (0,20) on the screen and give it a width and height.

To update the progressbar in time we need a QTimer().  We connect the widget with the timer, which calls the function increaseValue().  We set the timer to repeat the function call every 400 milliseconds.  You also see the words SLOT and SIGNAL.  If a user does an action such as clicking on a button, typing text in a box – the widget sends out a signal.  This signal does nothing, but it can be used to connect with a slot, that acts as a receiver and acts on it.

Result:

PyQT Progressbar
PyQT Progressbar

Download PyQT Code (Bulk Collection)


7 thoughts on “QT4 Progressbar

  1. Jahir Garcia - July 6, 2015

    hello, frank nice tutorials, Im really a beginner in python, but I use python on windows with arduino, I see on internet son gauge dial similar to this: https://developers.google.com/chart/interactive/docs/gallery/gauge, I see this example for do one dial with pyqt: http://stackoverflow.com/questions/12011147/how-to-create-a-3-color-gradient-dial-indicator-the-one-that-shows-green-yellow, Can you finished this example with numbers, and put published here. A question where are You from??

    1. Frank - July 6, 2015

      Hi Jahir, I’m from the netherlands. This is how to create a gauge dial with set and get value:

      import sys
      from PyQt4 import QtGui, QtCore, Qt
      import math
       
      class QtGauge(QtGui.QWidget):
       
          value = 1
       
          def __init__(self):
              super(QtGauge, self).__init__()
              self.initUI()
       
          def setValue(self,value):
              self.value = value
       
          def getValue(self):
              return self.value
       
          def initUI(self):      
       
              hbox = QtGui.QHBoxLayout(self)
              lbl = QtGui.QLabel(self)
       
              hbox.addWidget(lbl)
              self.setLayout(hbox)
              self.setGeometry(0, 0,600,600)
       
              self.move(300, 200)
              self.setWindowTitle('Dial Guage')
              self.show()  
       
          def paintEvent(self, e):
              painter = QtGui.QPainter()
              painter.begin(self)
              dial = QtGui.QPixmap("bg.png")
              #painter.drawPixmap(50, 50, 600, 600, dial)
       
              painter.setRenderHint(painter.Antialiasing)
              rect = e.rect()
       
              gauge_rect = QtCore.QRect(rect)
              size = gauge_rect.size()
              pos = gauge_rect.center()
              gauge_rect.moveCenter( QtCore.QPoint(pos.x()-size.width(), pos.y()-size.height()) )
              gauge_rect.setSize(size*.9)
              gauge_rect.moveCenter(pos)
       
              refill_rect = QtCore.QRect(gauge_rect)
              size = refill_rect.size()
              pos = refill_rect.center()
              refill_rect.moveCenter( QtCore.QPoint(pos.x()-size.width(), pos.y()-size.height()) )
              # smaller than .9 == thicker gauge
              refill_rect.setSize(size*.9)
              refill_rect.moveCenter(pos)
       
              painter.setPen(QtCore.Qt.NoPen)
       
              painter.drawPixmap(rect, dial)
       
              painter.save()
              grad = QtGui.QConicalGradient(QtCore.QPointF(gauge_rect.center()), 270.0)
              grad.setColorAt(.75, QtCore.Qt.green)
              grad.setColorAt(.5, QtCore.Qt.yellow)
              grad.setColorAt(.1, QtCore.Qt.red)
              painter.setBrush(grad)
              #painter.drawPie(gauge_rect, 225.0*16, self._value*16)
              painter.drawPie(gauge_rect, 225.0*16, -270*self.value*16)
              painter.restore()
       
              painter.setBrush(QtGui.QBrush(dial.scaled(rect.size())))
              painter.drawEllipse(refill_rect)
       
              super(QtGauge,self).paintEvent(e)   
              painter.end()
       
       
      def main():
          app = QtGui.QApplication(sys.argv)
          ex = QtGauge()
          ex.setValue(0.6)
          print ex.getValue()
          sys.exit(app.exec_())
       
       
      if __name__ == '__main__':
          main()

      The background:
      https://pythonspot.com/wp-content/uploads/2015/07/bg.png

      It will tell the value of the gauge and you can set it on the scale of 0 to 1. Is this what you had in mind?

      1. Jahir Garcia - July 8, 2015

        OK, Fantastic, But How I put the label values for scale on graphic. (0, 0.1, 0.2, 0.3 .. ….1), I see a beautiful gauges indicators in PYQT
        qt-apps.org/content/show.php/AnalogWidgets?content=87780
        But the code was writed for QT on C++, Is possible pass the code for use in PYQT windows??

        1. Frank - July 8, 2015

          Hi, it’s possible to put these programatically but it looks much better if you simply modify the pixmap. As far as I know these C++ widgets are not ported. I saw this version uses a textfont pixmap that is put on top of the gauge. This is one possibility but I don’t know the advantage as to simply changing the background pixmap.

          If you want to put a label on a pixmap programatically, you can do something like this:

          import sys
          from PyQt4 import QtGui, QtCore, Qt
          import math
           
          from PyQt4.QtCore import *
          from PyQt4.QtGui import *
           
          class QtGauge(QtGui.QWidget):
           
              value = 1
           
              def __init__(self):
                  super(QtGauge, self).__init__()
                  self.initUI()
           
              def setValue(self,value):
                  self.value = value
           
              def getValue(self):
                  return self.value
           
              def initUI(self):      
           
                  hbox = QtGui.QVBoxLayout(self)
                  palette = QtGui.QPalette()
           
                  # create a label
                  lbl = QtGui.QLabel(self)
                  palette.setColor(QtGui.QPalette.Foreground,QtCore.Qt.red)
                  lbl.setPalette(palette)
                  lbl.resize(400, 200)
                  lbl.setText("Text on label")
                  lbl.setFont(QtGui.QFont('Decorative', 40))
                  lbl.move(0,0)
           
                  hbox.addWidget(lbl)
           
                  self.setLayout(hbox)
                  self.setGeometry(0, 0,600,600)
           
                  self.move(300, 200)
                  self.setWindowTitle('Dial Guage')
                  self.show()  
           
              def paintEvent(self, e):
                  painter = QtGui.QPainter()
                  painter.begin(self)
                  dial = QtGui.QPixmap("bg.png")
           
                  painter.setRenderHint(painter.Antialiasing)
                  rect = e.rect()
           
                  gauge_rect = QtCore.QRect(rect)
                  size = gauge_rect.size()
                  pos = gauge_rect.center()
                  gauge_rect.moveCenter( QtCore.QPoint(pos.x()-size.width(), pos.y()-size.height()) )
                  gauge_rect.setSize(size*.9)
                  gauge_rect.moveCenter(pos)
           
                  refill_rect = QtCore.QRect(gauge_rect)
                  size = refill_rect.size()
                  pos = refill_rect.center()
                  refill_rect.moveCenter( QtCore.QPoint(pos.x()-size.width(), pos.y()-size.height()) )
                  refill_rect.setSize(size*.9)
                  refill_rect.moveCenter(pos)
           
                  painter.setPen(QtCore.Qt.NoPen)
           
                  painter.drawPixmap(rect, dial)
           
                  painter.save()
                  grad = QtGui.QConicalGradient(QtCore.QPointF(gauge_rect.center()), 270.0)
                  grad.setColorAt(.75, QtCore.Qt.green)
                  grad.setColorAt(.5, QtCore.Qt.yellow)
                  grad.setColorAt(.1, QtCore.Qt.red)
                  painter.setBrush(grad)
                  painter.drawPie(gauge_rect, 225.0*16, -270*self.value*16)
                  painter.restore()
           
                  painter.setBrush(QtGui.QBrush(dial.scaled(rect.size())))
                  painter.drawEllipse(refill_rect)
           
                  super(QtGauge,self).paintEvent(e)   
                  painter.end()
           
           
          def main():
              app = QtGui.QApplication(sys.argv)
              ex = QtGauge()
              ex.setValue(0.6)
              print ex.getValue()
              sys.exit(app.exec_())
           
           
          if __name__ == '__main__':
              main()

          However, I recommend changing the background image itself because it’s more slick. If I get some more time today I may look into it deeper. I hope that helps 🙂

          1. Jahir Garcia - July 10, 2015

            Great..!! Perfect, last thing, Please see this project: http://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.ArduinoExpertSerieDepuisPCSliderPWMVarieLEDPyQt
            I download and modify some lines for use in windows, I want put this gauge in up position of slider, and the text label gauge in center of gauge, for read analog input.
            Do you are teacher in School?? You have a lot of patience to teach..

            1. Frank - July 11, 2015

              Looking into it

            2. Frank - July 16, 2015

              Hi Jahir, sorry for the delay has been hectic here. You can download these files and open them in a program named QTCreator. With this program you can drag & drop widgets. No, I’m just a 27 year old software developer 🙂