Unsolved QProgressDialog looks messed up / corrupted when it's first shown
-
@Guerrian Hi,friend.
Very good! Don't forget to
Mark as Solved
inTopic Tools
. -
If you don't pause before the first (not zero) point and process events then the progress dialogue is drawn correctly. Seems like a bug with QProgressDialog.
-
@Guerrian
Hi
QProgressDialog is older than god so its very unlikely you found a bug in 2018 :)
also when you use stuff like
QApplication::processEvents();
QThread::sleep(1);
it means you try to loop in a GUI application and it always do odd stuff as you are stangulating the event loop. QApplication::processEvents() can sometimes help
but its not a cure all loops magic call.signals and slot often a way better choice as it plays nice with the event loop.
-
@mrjj
Can I do this with two threads, one for the GUI and the other for the algorithm? -
@Guerrian
Hi, yes if algorithm is heavy then its be best solution.
You already have the GUI thread.
So if you move the algorithm class to a thread and
emit a signal to tell the progressbar to update then it should work lovely.
https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
so myAlgorithm would be the task object and moved to thread. -
I followed this path and it is almost working. Unfortunately the cancel button on the progress bar is disabled. It remains disabled even after successfully updating the progress bar. The only thread I could find on this problem is here:
https://forum.qt.io/topic/26619/cancel-button-on-qprogressdialog-is-unresponsive-solved
Like the author says though you don't need to connect the cancel button to a slot.I am setting up the dialog like this now:
dialog = new QProgressDialog(tr("Performing task") + "...", tr("Cancel"), 0, 4, this); dialog->setLabelText("Updating..."); dialog->setWindowModality(Qt::WindowModal); connect(task, SIGNAL(advance()), this, SLOT(advance())); connect(dialog, &QProgressDialog::finished, dialog, &QProgressDialog::deleteLater); connect(dialog, &QProgressDialog::canceled, this, [=] () { thread->quit(); thread->wait(); dialog->close(); });
I'm showing the dialog like this:
dialog->setValue(0); dialog->show();
I'm advancing the progress bar like this:
void MainWindow::advance() { dialog->setValue(dialog->value() + 1); QApplication::processEvents(); }
Another strange problem which I am encountering is that the progress bar / task is sometimes started even when I click on the menu but not the menu item. I am connecting the menu item to the function using:
connect(ui->actionTask, &QAction::triggered, this, &MainWindow::runTask);
-
Hi
Does it enter the "cancel" lambda ? -
@mrjj
No, it can't, because the cancel button is disabled on the QProgressDialog. -
But do you mean is disabled as in setEnabled(false)
or simply is unresponsive ? -
@mrjj
I think the problem is that I disabled the menu using:setEnabled(false);
When I click cancel the lambda is called twice.
However I don't understand why the action is triggered even when I just select the menu and not the menu item. Perhaps this merits another question on this forum.
Is it neccessary to use a mutex and flag that the algorithm has been cancelled?