3

I create a progress bar using the code below on the QGIS console. However, the bar freezes in the beginning, doesn't increase at all, and suddenly appears as 100% in the end.

What could be the reason for not showing the increase in the intermediate steps?

from PyQt5.QtWidgets import * 
import time

pb = QProgressBar()
pb.resize(300, 40)
pb.setWindowTitle('Working...')
pb.show()

total = 5
for i in range(1, total + 1):
    time.sleep(1)
    pb.setValue(i / total * 100)

1 Answer 1

4

Set the parent widget of the progress bar to the main window of QGIS or one of it's children. If you want to set the progress bar parent to the QGIS main window try this: pb = QProgressBar(iface.mainWindow())

If you need to change the position of the progress bar with reference to the parent widget, use the method move(x, y)

If you need something like a dialog use this code:

from PyQt5.QtWidgets import * 
import time

main_window = iface.mainWindow()
task_mgr = QgsApplication.taskManager()

def show_pb(task):
    qd = QDialog(main_window)
    qd.setWindowTitle('Working...')
    qd.resize(300, 40)

    pb = QProgressBar(qd)
    pb.resize(300, 40)

    pb.show()
    qd.show()
    total = 5
    for i in range(1, 5+1):
        time.sleep(1)
        pb.setValue(int(i/5*100))
    return pb.close()

task = QgsTask.fromFunction('my task', show_pb)
task_mgr.addTask(task)

Here I use the QGIS task manager to prevent the progress bar from freezing, documentation here. There is a problem with this way, that when the task is completed, qgis will show a notification and there is no way to hide it in the Python API.

I don't know much about the threading module. This in a very basic implementation, this way you can prevent QGIS from showing you a notification every time the progress bar finishes.

import time
import threading

main_window = iface.mainWindow()

def show_pb(parent):
    qd = QDialog(main_window)
    qd.setWindowTitle('Working...')
    qd.resize(300, 40)

    pb = QProgressBar(qd)
    pb.resize(300, 40)

    pb.show()
    qd.show()
    total = 5
    for i in range(1, 5+1):
        time.sleep(1)
        pb.setValue(int(i/5*100))
#    return qd.close() uncomment this line to close the dialog when the progress bar reaches 100%

task = threading.Thread(target=show_pb, args=(main_window, ))
task.start()
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.