2

Before long operation is executed, I'm invoking QProgressDialog to inform user about the progress of the execution. The long operations is waiting for thread to be terminated.

The problem is, when I use show method of QProgressDialog, the progress dialog is not fully constructed and the thread goes into the wait method of the thread, as you can see on the figure below:

1

Meanwhile when I use exec method of the QProgressDialog, the progress dialog is fully constructed, but the wait method is not invoked until I exit the progress dialog, as you can see here:

2

This is the code I'm using:

auto dialog = new QProgressDialog();
dialog->setWindowTitle("Wait");
dialog->setLabelText("Aborting optimization");

dialog->resize(100, 30);
dialog->show();

optimizerUi->terminate();
optimizerUi->wait();

dialog->hide();

Is there any way I can wait for or force the progress dialog to be fully constructed before the thread falls into the wait method, which takes quite a long time and blocks the main thread? Thank you for any suggestion.

kocica
  • 6,412
  • 2
  • 14
  • 35
  • What kind of object is optimizerUi? You want to have its terminate method emit a signal, then connect that signal to the close method of your dialog. Blocking the UI by calling wait is not good. – Botje Nov 22 '20 at 23:24
  • I don't think your dialog is not fully constructed, but `wait()` is executing, blocking the dialog from updating the view. Both `exec()` and `wait()` block the main thread, so you cannot run both at the same time. – Minh Nov 23 '20 at 07:59
  • @Botje `optimizerUi` is a `QThread`. It takes a while before it is terminated because its performing complex operation. @NgocMinhNguyen Alright, then I have to use `show()` method of the `dialog`, but then the dialog has no content, is there any way I can show the dialog properly and then terminate the thread (and call `wait()`)? Thanks for replies. – kocica Nov 23 '20 at 10:10
  • 2
    I suppose I can connect `QThread::finished()` signal to `dialog.hide()` slot, and don't call `wait()` at all, just disable appropriate button(s) until thread's `finished` signal is emitted. – kocica Nov 23 '20 at 10:14
  • 1
    Indeed. Letting the signals do the work for you is the proper way. Never block the event loop. – Botje Nov 23 '20 at 10:20

1 Answers1

2

You can wait for the thread to finish with some timeout. If the thread is finished, close the progress dialog. If it isn't, process the application events.

auto dialog = new QProgressDialog();
dialog->setWindowTitle("Wait");
dialog->setRange(0, 0);
dialog->setLabelText("Aborting optimization");
dialog->setCancelButton(nullptr);

dialog->resize(100, 30);
dialog->show();

optimizerUi->terminate();
while (!optimizerUi->wait(QDeadlineTimer{100}))
{
    QApplication::processEvents();
}
dialog->hide();
Minh
  • 1,630
  • 1
  • 8
  • 18