Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QProgressBar causing bad performance in QT5?
QtWS25 Last Chance

QProgressBar causing bad performance in QT5?

Scheduled Pinned Locked Moved Solved General and Desktop
pyqt5python3qprogressbarperformance
3 Posts 2 Posters 1.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    Trunks10
    wrote on 23 Apr 2016, 13:00 last edited by Trunks10
    #1

    I'm developping a program which parses a file (365000 lines) in which I try to match some keywords after reading each line. This computation along with the update of my QProgressBar are made in another thread using QThread. Everything works fine except for the performance especially when I update the QProgressBar. I use a timer for the parsing and the result is just STUNNING. When I emit a signal to update the QProgressBar the program takes around 45 seconds but when I do not emit the signal for the QProgressBar update then the program takes around 0.40 sec =/

    from PyQt5 import QtCore, QtWidgets, QtGui
    import sys
    import time
    
    liste = ["failed", "exception"]
    
    class ParseFileAsync(QtCore.QThread):
    
        match = QtCore.pyqtSignal(str)
        PBupdate = QtCore.pyqtSignal(int)
        PBMax = QtCore.pyqtSignal(int)
    
        def run(self):        
            cpt = 0
            with open("shutdown_issue_1009.log", "r") as fichier:
                fileLines = fichier.readlines()  
                lineNumber = len(fileLines)    
                self.PBMax.emit(lineNumber)
            
                t0 = time.time()
                for line in fileLines:
                    cpt+=1
                    self.PBupdate.emit(cpt)   
                    for element in liste:
                        if element in line:
                            self.match.emit(line)
            
            finalTime = time.time() - t0
            print("over :", finalTime)
    
        class Ui_MainWindow(QtWidgets.QMainWindow):
    
            def __init__(self):
                super().__init__()       
                self.setupUi(self)
                self.thread = ParseFileAsync()
        
                self.thread.match.connect(self.printError)
                self.thread.PBupdate.connect(self.updateProgressBar)
                self.thread.PBMax.connect(self.setMaximumProgressBar)
        
                self.pushButton_GO.clicked.connect(self.startThread)
    
            def printError(self, line):
                self.textEdit.append(line)
    
            def updateProgressBar(self, value):
                self.progressBar.setValue(value)
        
            def setMaximumProgressBar(self, value):
                self.progressBar.setMaximum(value)
        
            def startThread(self):
                self.thread.start()
    

    Console output:

    over : 44.49321101765038  //QProgressBar updated
    over : 0.3695987798147516 //QProgressBar not updated (#self.PBupdate.emit(cpt))
    

    Am I missing something or is that expected ?

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mrjj
      Lifetime Qt Champion
      wrote on 23 Apr 2016, 14:02 last edited by
      #2

      Hi
      I dont know python, but if in a c++ application
      i would try the same
      with no slot connected to see if it was sending the signal
      very fast that was the issue.
      So try to emit but dont respond to it.
      If still fast i would look at the slot.
      Using Progressbar in c++, i didn't notice such huge difference and painting
      the bar etc should not be so expensive.

      But if it takes 0.3 sec. do u really need a progress bar anyway?

      1 Reply Last reply
      0
      • T Offline
        T Offline
        Trunks10
        wrote on 23 Apr 2016, 22:05 last edited by Trunks10
        #3

        I did the test and appearantly it's the painting which is very expensive... with no slot connected, the program takes 1,5 seconds to complete the task. There is a very similar issue reported at https://bugreports.qt.io/browse/QTBUG-49655.

        But generally ProgressBars are consuming especially when we update it that often (>365000 times) while there is no significant change at each iteration. So I simply update the QProgressBar less often and the results are good (~1s) and the progression still smooth. PSB :

        class ParseFileAsync(QtCore.QThread):
            
            match = QtCore.pyqtSignal(str)
            PBupdate = QtCore.pyqtSignal(int)
            PBMax = QtCore.pyqtSignal(int)
        
            def run(self):        
                with open("test_long.log", "r") as fichier:
                    fileLines = fichier.readlines()  
                    self.lineNumber = len(fileLines)
                    self.PBMax.emit(self.lineNumber)
        
                    if (self.lineNumber < 30):
                        self.parseFile(fileLines, False)
                    else:
                        self.parseFile(fileLines, True)
            
            def parseFile(self, fileLines, isBig):                
                    cpt = 0
                            
                    if(isBig):
                        for line in fileLines:
                            cpt+=1             
                            if(cpt % (int(self.lineNumber/30)) == 0):
                                self.PBupdate.emit(cpt)        
                            for element in liste:
                                if element in line:
                                    self.match.emit(line)
                        
                        self.PBupdate.emit(self.lineNumber) #To avoid QProgressBar stopping at 99%
                    else:         
                        for line in fileLines:
                            cpt+=1                
                            self.PBupdate.emit(cpt)                                  
                            for element in liste:
                                if element in line:
                                    self.match.emit(line)
        
        1 Reply Last reply
        0

        1/3

        23 Apr 2016, 13:00

        • Login

        • Login or register to search.
        1 out of 3
        • First post
          1/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved