PyQt5 How to make updating progress bar when line from text is reading?
-
Hi, I want to do simple UI - click button opens file dialog, next choose text file and it's adding to list line by line. And this part works fine. When file has about 500k lines adding takes some time, so decided to make a progress bar. I was searching how to do this and here is my code:
SIZE = 0 VALUE = 0 class External(QtCore.QThread): countChanged = QtCore.pyqtSignal(int) def run(self): while VALUE <= SIZE: time.sleep(0.01) counter = VALUE self.countChanged.emit(counter) class Ui_MainWindow(object): def setupUi(self, MainWindow): \... some UI setup ...\ self.listView = QtWidgets.QListWidget() self.pushButton = QtWidgets.QPushButton() self.pushButton.clicked.connect(self.openFile) self.progressBar = QtWidgets.QProgressBar() def openFile(self): openfile = QFileDialog.getOpenFileName(self.pushButton, "Open File", "", "TXT (*.txt)") global SIZE global VALUE SIZE = os.stat(openfile[0]).st_size self.progressBar.setMinimum(0) self.progressBar.setMaximum(SIZE) if not openfile[0] == "": with open(openfile[0], 'r') as f: file_text = f.readlines() self.calc = External() self.calc.countChanged.connect(self.onCountChanged) self.calc.start() for line in file_text: VALUE = VALUE + len(line) self.listView.addItem(line) VALUE = SIZE def onCountChanged(self, counter): self.progressBar.setValue(counter)
Text is added to list properly each time, but progress bar isn't updated, it looks as the progress value was added after loading the entire list to 100%.
Why my progress bar doesn't work properly? What the code should look like?
Thank you for your interest. -
Hi and welcome to the forums
In a GUI app, there is an always running loop called the event loop.When you in your code make a long loop - you prevent this loop from running and
the app won't get signals or events until your loop is finished. (you hang it, we say)That is why ProgressBar first can redraw after the loop.
The ugly way of fixing this is calling
app.processEvents()
in the
for line in file_text:
as that allows paint messages and signals to have a chance to run.The more clean way is to use a Thread to do the reading.
Like here
https://stackoverflow.com/questions/34419926/how-to-make-qtgui-window-process-events-whenever-it-is-brought-forward-on-the-sc