QProgressDialog does not take input unless the progress value changes
-
When you block the event loop - how should the ui be redrawn? Use the canceld() signal and don't block the event loop...
-
At some point the mouse events need to be processed. For this the event loop needs to run. It is very likely that you are blocking the event loop. There might be some weird behavior when calling setValue with a different progress that uses some direct connection to update the progress bar and also somehow processes the mouse event.
As a quick test you can call QApplication::processEvents() right before your call to wasCanceled() to see if this solves your problem. If it does you are definitely blocking the event loop. However, don't use this trick as your final solution. Your current loop will take about 100 times longer if you do this. It is not worth to slow down your actual processing by 100x just to have a nice UI.
Instead, then your solution should be to use a separate worker thread. You are not allowed to call any UI functions from the worker thread: no call to wasCanceled and no call to setValue. Instead you need to use signals and slots to connect these function calls.
-
@JanLaloux You’re right! Manually incrementing and resetting the progress value is not ideal. A cleaner approach could be calling QCoreApplication::processEvents() inside your loop to allow UI events (like button clicks) to be processed without artificially changing the progress value. You might also try setAutoReset(false) or setMinimumDuration(0) to see if it improves responsiveness.
-
@andrewmorgan
It would not be ideal to callprocessEvents()
. It would be better to allow the main event loop to run and raise and act on thecanceled()
signal, as previously written. -
Thanks all for the valuable input!
@SimonSchroeder: the test with QApplication::processEvents() is positive, the problem goes away.
BUT: the implementation is as documented for the QProgressDialog Class for the modal operation:
"Compared to a modeless QProgressDialog, a modal QProgressDialog is simpler to use for the programmer. Do the operation in a loop, call setValue() at intervals, and check for cancellation with wasCanceled(). "
So with the functions, not the signals.
And since it is the intention that the user cannot do anything than either wait for the operation to finish, or to cancel it, this seems to me correct for the modal operation? -
@JonB said in QProgressDialog does not take input unless the progress value changes:
It would not be ideal to call processEvents()
The only valid use case for
processEvent()
to update the progress ofQProgressDialog
/QProgressBar
is when using it in combination with tasks that run inmain.cpp
before the event loop is even started or like everythingQSplashScreen
related... -
@JanLaloux said in QProgressDialog does not take input unless the progress value changes:
Compared to a modeless QProgressDialog, a modal QProgressDialog is simpler to use for the programmer. Do the operation in a loop, call setValue() at intervals, and check for cancellation with wasCanceled(). "
So with the functions, not the signals.We should adjust the documentation... blocking the event loop is a bad idea.