2

I'm building a QGIS plugin and I want to improve the user interface. I'm able to use processing tools like buffer, but with heavy layers I want to display a progress bar, users can easily see the treatment progression.

In documentation, there is some words about it but when I run simples examples, QGIS systematicaly not responding and there isn't any progress bar. Note that this treatment works perfectly without this progress bar issue.

Here is my code :

import time
from qgis.PyQt.QtWidgets import QProgressBar
from qgis.PyQt.QtCore import *

# Progress bar
progressMessageBar = iface.messageBar().createMessage("Work in progress...")
progress = QProgressBar()
progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
progressMessageBar.layout().addWidget(progress)
iface.messageBar().pushWidget(progressMessageBar, Qgis.Info)

# Layer
vlayer = qgis.utils.iface.activeLayer()
count = vlayer.featureCount()
features = vlayer.getFeatures()

# Progression loop
for i, feature in enumerate(features):    
    percent = i / float(count) * 100
    # My treatment
    processing.runAndLoadResults('native:buffer', {"INPUT": vlayer, "DISTANCE": 20, "OUTPUT": 'memory:buffer'})
    # Progression status
    iface.statusBarIface().showMessage("Processed {} %".format(int(percent)))
    progress.setValue(percent)

iface.statusBarIface().clearMessage()

Am I missing something ? Maybe something is wrong in my loop. I'm working with QGIS 3.10.1.

7
  • 2
    look at this gis.stackexchange.com/a/312997/49538 – Fran Raga Jan 24 '20 at 17:51
  • I've seen this post before and i'm ok with this, i can display a percentage progression in the python console. But how can i assign this to a bar ? (like a classic QgsMessageBar()) – GeoGyro Jan 24 '20 at 18:02
  • To see if I understand, the progress bar is not showing in the status bar, right?. Have you try adding time.sleep(1) like in the doc example, just to check. – cabesuon Jan 24 '20 at 18:47
  • That's it. No problem with the first message (Work in progress), but after nothing and QGIS freeze. It seems there is a bug with my loop (like if the treatment apply in all the layer for each feature). – GeoGyro Jan 24 '20 at 19:07
  • 2
    In your code, it seems you are doing a loop for each feature in your layer, but you give your layer to the processing algorithm. Is-it corect? Are you sure you don't get duplicated layers? I will write a better anwser tomorrow. – etrimaille Jan 24 '20 at 22:17
3

With researches, i made this acceptable answer, without any loop. I assign QgsProcessingFeedback() to QProgressBar() and get a dynamic progression bar when processing is running :

# Progression bar
qgis.utils.iface.messageBar().clearWidgets()
progressMessageBar = qgis.utils.iface.messageBar()
progressbar = QProgressBar()
progressMessageBar.pushWidget(progressbar)

# Processing feedback
def progress_changed(progress):
    #print(progress)
    progressbar.setValue(progress) 

f = QgsProcessingFeedback()
f.progressChanged.connect(progress_changed)

# Layer and processing
vlayer = qgis.utils.iface.activeLayer()
processing.runAndLoadResults('native:buffer', {"INPUT": vlayer, "DISTANCE": 20, "OUTPUT": 'memory:buffer'}, feedback=f)

# Clear the message bar when done
qgis.utils.iface.messageBar().clearWidgets()

Thanks to all, you put me on the good track.

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.