I have a function which writes a report based on technologies selected by the user via QCheckBoxes. Depending on the number of technologies chosen, the QProgressBar will go through set values until the function reaches completion.
For example:
1 tech: 0 -> 99 -> 100
2 tech: 0 -> 50 -> 99 -> 100
3 tech: 0 -> 33 -> 66 -> 99 -> 100
4 tech: 0 -> 25 -> 50 -> 75 -> 99 -> 100
Regardless of the number of technologies chosen, once the last one has been processed, the progressbar would be set to 99
to do some textual clean up before reaching 100
.
At the moment, I have two such technologies (PV and wind turbine) where I manually set the progress values.
How could I achieve the above in a more systematic fashion?
My current code:
def report(self):
# Define progress bar
progressMessageBar = iface.messageBar().createMessage(str('Generating report...'))
progress = QProgressBar()
progress.setMaximum(100)
progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
progressMessageBar.layout().addWidget(progress)
iface.messageBar().pushWidget(progressMessageBar, iface.messageBar().INFO)
progress.setValue(0)
sleep(5)
# Define Report text browser
display_report = self.report_dockwidget.report_textBrowser
# Technology checkboxes
pv_checkBox = self.pv_generation_dockwidget.returnResults_Checkbox
wind_checkBox = self.wind_generation_dockwidget.returnResults_Checkbox
# For PV
if pv_checkBox.isChecked():
# Do some processing
progress.setValue(50)
if not wind_checkBox.isChecked():
progress.setValue(99)
sleep(5)
# For Wind
if wind_checkBox.isChecked():
# Do some processing
if not pv_checkBox.isChecked():
progress.setValue(50)
else:
progress.setValue(99)
sleep(5)
# Do some cleanup
progressMessageBar.setText('Complete')
progress.setValue(100)
sleep(1)
# Show report
self.report_dockwidget.show()
2 Answers 2
One idea would be to gather all your techs in a queue and iterate over that, updating the progress as you go.
Since my Python is rather Rust-y (I'm sorry for that pun), here's some pseudocode:
# Setup progress bar et cetera
# Gather techs in a queue
techs = Queue()
if pv_checkBox.isChecked():
techs.add(pv_task)
if wind_checkBox.isChecked():
techs.add(wind_task)
# Do the work
total_tasks = techs.count()
done_tasks = 0
while not techs.isEmpty():
task = techs.take()
task.doWork()
done_tasks += 1
new_progress = max(done_tasks / total_tasks * 100, 99)
progress.setValue(newProgress)
# Progress is now 99
doFinalStuff()
progress.setValue(100)
This will do all the tasks in a FIFO fashion and set the progress as you wanted with the last step always being 99.
Now, it would be a good idea to gather all checkboxes in a group or layout and, by getting and filtering all child elements, add the techs via loop as well.
-
\$\begingroup\$ Thanks for your answer! Interesting, never used
Queue()
before so will test this at some point and report back :) \$\endgroup\$Joseph– Joseph2017年12月05日 13:58:49 +00:00Commented Dec 5, 2017 at 13:58
Thanks to @PhilKiener's answer, I translated his pseudocode with the relevant methods for Python 2.7 which works well:
# Setup progress bar et cetera
# Gather techs in a queue
techs = Queue.Queue()
if pv_checkBox.isChecked():
techs.put(pv_task)
if wind_checkBox.isChecked():
techs.put(wind_task)
# Do the work
total_tasks = len(techs.queue)
done_tasks = 0
while not techs.empty():
task = techs.get()
done_tasks += 1
new_progress = int(ceil(float(done_tasks) / float(total_tasks) * 99))
progress.setValue(new_progress)