Home > OS >  Loading bar job doesn't render till job is complete PyQt5
Loading bar job doesn't render till job is complete PyQt5

Time:04-25

I have created a UI using PyQt5 that contains a progress bar. I have coded this progress bar in python so that it increases to 99% in real time. The problem I am facing is that the window does not load until the job is complete. I have read upon similar posts which talk about threading and I cannot possibly grasp anything from it. I would appreciate if someone could explain to me a solution and if it does require threading, an aspect I am yet to learn, please explain it to me in laymans term.

import sys, os, sqlite3
import random, datetime
from PyQt5 import QtCore, QtGui, uic
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5 import QtWidgets 
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, 
QMessageBox, QProgressBar, QSplashScreen
import sqlite3
import time


window2 = uic.loadUiType("login_loadingbar.ui")[0]


class LoadingBar(QtWidgets.QMainWindow, window2): 
   def __init__(self, parent=None):
       QtWidgets.QMainWindow.__init__(self, parent)
       self.setupUi(self)
        
       #title
       self.setWindowTitle('Loading')

        
        
    
    #makes progress bar go from 0-100, time scaled
    def progress(self):
        for i in range(100):
            time.sleep(0.1)
            self.login_progressBar.setValue(i)
        


app = QApplication(sys.argv)
w2 = LoadingBar(None)
w2.show()
w2.progress()
app.exec_()

CodePudding user response:

When you create gui application you have one thread, in this thread there's thing called event loop - its essentially while true loop that handles events - redraws widgets when necessary, dispatches keyboard and mouse input to related widgets.

Since you have only one thread you can only do one thing at a time, so when you do long operation like time.sleep(), event loop is frozen - no widgets gets redrawn, no inputs handled until it completes and next iteration of event loop reached.

You can create second thread and move operation there or in simple cases when operation can be split into pieces - process events in event loop in between pieces:

for i in range(100):
    time.sleep(0.1)
    self.login_progressBar.setValue(i)
    QtWidgets.QApplication.processEvents()

This way event loop kinda works, but application is not 100% responsive, because every time.sleep(0.1) freezes it, so mouse clicks and other events may not be handled.

  • Related