Search code examples
timerpyqtpyqt5progress-barqtimer

Timer delay in round proress bar of PYQt5


In PYQT5, I want to increase the progress of the round progress bar in UI after every 10 minutes by using PyQt5 for 90 minutes. I have tried 2 methods 1st by time.sleep() and 2nd by Qtimer.

1st method "time.sleep"

import sys
import os
from datetime import time

import qdarkstyle
from ui_main import *
progress_val = 0

class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
    # APPLY QDARKSTYLE THEME
    self.setStyleSheet(qdarkstyle.load_stylesheet_pyside2())

    # SET PROGRESS BAR VALUE
    self.ui.progressBar.rpb_setMaximum(420)

    # SET PROGRESS BAR STYLE
    self.ui.progressBar.rpb_setBarStyle('Donet')

    # SET PROGRESS BAR LINE COLOR
    self.ui.progressBar.rpb_setLineColor((0, 170, 255))  # ARGUMENT RGB AS A TUPLE

    # CHANGING THE PATH COLOR
    self.ui.progressBar.rpb_setPathColor((255, 30, 99))

    # SET PROGRESS BAR TEXT COLOR
    self.ui.progressBar.rpb_setTextColor((233, 30, 99))  # ARGUMENT RGB AS A TUPLE

    # SET PROGRESS BAR STARTING POSITION
    # North, East, West, South
    self.ui.progressBar.rpb_setInitialPos('West')  # WEST AS STARTING POSITION.

    # SET PROGRESS BAR TEXT TYPE : VALUE OR PERCENTAGE
    # Value, Percentage
    self.ui.progressBar.rpb_setTextFormat('Percentage')

    # SET PROGRESS BAR FONT
    self.ui.progressBar.rpb_setTextFont('Arial')

    # TEXT HIDDEN
    self.ui.progressBar.rpb_enableText(False)

    # SET PROGRESS BAR LINE WIDTH
    self.ui.progressBar.rpb_setLineWidth(10)

    # PATH WIDTH
    self.ui.progressBar.rpb_setPathWidth(15)

    # SET PROGRESS BAR LINE CAP
    # RoundCap, SquareCap
    self.ui.progressBar.rpb_setLineCap('RoundCap')

    # LINE STYLE
    # DotLine, DashLine
    self.ui.progressBar.rpb_setLineStyle('DotLine')

    #######################################################################
    ## SHOW ==> MAIN WINDOW
    ########################################################################
    self.show()
    ## == #

    # ANIMATE THE PROGRESS
    # LETS ADD TIMER TO CHANGE PROGRESSES
    # self.timer = QtCore.QTimer()
    # self.timer.timeout.connect(self.progress)  # progress function
    # self.timer.start(60000)
    #
    # # Change all progresses to zero on start
    # QtCore.QTimer.singleShot(0, lambda: self.ui.progressBar.rpb_setValue(0))

def progress(self):
    global progress_val
    # Set progress values
    self.ui.progressBar.rpb_setValue(progress_val)

    time.sleep(60)
    # Reset progresses if the maximum value is reached
    if progress_val > 420:
        progress_val = 0;

    # Increase value every 60 ms
    progress_val += 1


########################################################################
## EXECUTE APP
########################################################################
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec_())
########################################################################
## END===>
########################################################################

Output:
In the first method, I used timer.sleep() but the UI got stuck.
2nd method "QTimer"

import sys
import os
from datetime import time

import qdarkstyle
from ui_main import *
progress_val = 0


class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

    # APPLY QDARKSTYLE THEME
    self.setStyleSheet(qdarkstyle.load_stylesheet_pyside2())

    # SET PROGRESS BAR VALUE
    self.ui.progressBar.rpb_setMaximum(420)

    # SET PROGRESS BAR STYLE
    self.ui.progressBar.rpb_setBarStyle('Donet')

    # SET PROGRESS BAR LINE COLOR
    self.ui.progressBar.rpb_setLineColor((0, 170, 255))  # ARGUMENT RGB AS A TUPLE

    # CHANGING THE PATH COLOR
    self.ui.progressBar.rpb_setPathColor((255, 30, 99))

    # SET PROGRESS BAR TEXT COLOR
    self.ui.progressBar.rpb_setTextColor((233, 30, 99))  # ARGUMENT RGB AS A TUPLE

    # SET PROGRESS BAR STARTING POSITION
    # North, East, West, South
    self.ui.progressBar.rpb_setInitialPos('West')  # WEST AS STARTING POSITION.

    # SET PROGRESS BAR TEXT TYPE : VALUE OR PERCENTAGE
    # Value, Percentage
    self.ui.progressBar.rpb_setTextFormat('Percentage')

    # SET PROGRESS BAR FONT
    self.ui.progressBar.rpb_setTextFont('Arial')

    # TEXT HIDDEN
    self.ui.progressBar.rpb_enableText(False)

    # SET PROGRESS BAR LINE WIDTH
    self.ui.progressBar.rpb_setLineWidth(10)

    # PATH WIDTH
    self.ui.progressBar.rpb_setPathWidth(15)

    # SET PROGRESS BAR LINE CAP
    # RoundCap, SquareCap
    self.ui.progressBar.rpb_setLineCap('RoundCap')

    # LINE STYLE
    # DotLine, DashLine
    self.ui.progressBar.rpb_setLineStyle('DotLine')

    #######################################################################
    ## SHOW ==> MAIN WINDOW
    ########################################################################
    self.show()
    ## == #

    # ANIMATE THE PROGRESS
    # LETS ADD TIMER TO CHANGE PROGRESSES
    # self.timer = QtCore.QTimer()
    # self.timer.timeout.connect(self.progress)  # progress function
    # self.timer.start(60000)
    #
    # # Change all progresses to zero on start
    # QtCore.QTimer.singleShot(0, lambda: self.ui.progressBar.rpb_setValue(0))

def progress(self):
    global progress_val
    # Set progress values
    self.ui.progressBar.rpb_setValue(progress_val)

    # time.sleep(60)
    # Reset progresses if the maximum value is reached
    if progress_val > 420:
        progress_val = 0;

    # Increase value every 60 ms
    progress_val += 1


########################################################################
## EXECUTE APP
########################################################################
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec_())
########################################################################
## END===>
########################################################################

after implementation, the code progress is not made in the expected time. for example, I gave 1 minute means timer.start(6000) but the progress bar takes longer than 1 minute to increase.

ui_main.py

from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *

from PySide2extn.RoundProgressBar import roundProgressBar


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(502, 266)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.verticalLayout = QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName(u"verticalLayout")
        self.progressBarContainer = QFrame(self.centralwidget)
        self.progressBarContainer.setObjectName(u"progressBarContainer")
        self.progressBarContainer.setFrameShape(QFrame.StyledPanel)
        self.progressBarContainer.setFrameShadow(QFrame.Raised)
        self.verticalLayout_2 = QVBoxLayout(self.progressBarContainer)
        self.verticalLayout_2.setObjectName(u"verticalLayout_2")
        self.progressBar = roundProgressBar(self.progressBarContainer)
        self.progressBar.setObjectName(u"progressBar")
        self.progressBar.setMinimumSize(QSize(200, 200))
        self.progressBar.setMaximumSize(QSize(200, 200))

        self.verticalLayout_2.addWidget(self.progressBar, 0, Qt.AlignHCenter|Qt.AlignVCenter)


        self.verticalLayout.addWidget(self.progressBarContainer)

        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)

        QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))

Solution

  • I think you have the right idea with using the QTimer, But I would just use the timer for it's timed signal emitter, and update the progress bar based on the system clock using time.time().

    like this:

    
    class MainWindow(QMainWindow):
    
        def __init__(self):
            QMainWindow.__init__(self)
            self.start_time = time.time()
            ...
    
    
            self.show()
            self.timer = QTimer()
            self.timer.timeout.connect(self.progress)
            self.timer.start(1000)  # this will emit every second 
    
        def progress():
            if time.time() - self.start_time >= 420:  # this would be 420 seconds
                self.start_time = time.time()
            self.ui.progressBar.rpb_setValue(time.time() - self.start_time)
    
    ...