-1

I'm working with code where next group of calls is frequently used:

    QDialog my_qDialog(my_parent);
    my_qDialog->setModal(false);
    my_qDialog->hide();
    my_qDialog->show();
    my_qDialog->exec();

I haven't found nothing about using of both show() + exec() in a raw. As a result parent isn't blocked and the code next to "exec()" performs only after dialog closing.

The question is: Is it normal to use such code? Maybe it has disadvantages? Can I freely interact with parent while exec() is running?

Thanks in advance for any help you can provide

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
Igor
  • 53
  • 3
  • 2
    It's not clear why do you need to use both `show()` and `exec()` together? – vahancho Apr 05 '18 at 07:46
  • You should either connect to the `QDialog::finished` signal and use `show()` so your program logic can keep running while the dialog is shown (you declare it to be non-modal, so that would make the most sense). Or you use `exec()` so the code is blocking until the dialog is done. I don't thing there is any point in using `show()` and then `exec()`. – Elijan9 Apr 05 '18 at 07:52
  • @vahancho, Thanks for your responses. The history of implementation was next: 1. Typical logic: all the dialogs are called with exec(); 2. Request: by pressing the button hide current dialog and all the hierarchy (and show small dialog for restoring) to have a possibility to interact with main window. 2.1 So the exec() was replaced with show()+exec(). Was it wrong solution? Maybe solution required all the logic changing from exec() to show()? – Igor Apr 05 '18 at 08:35

1 Answers1

1

You're re-entering the event loop in exec(). Generally speaking, that invites disaster if you're not careful. By doing it, you're pretending that something happens that isn't true. The world is asynchronous. If you wish to streamline your code, you can rewrite it in continuation-passing style, where the continuation will be invoked from the top-level event loop.

You can even factor this code out:

template<typename T>
T *show(std::function<void(QDialog*)> fun) {
  show({}, std::move(fun));
}

template<typename T>
T* show(QWidget *parent, std::function<void(QDialog*)> fun) {
  auto dialog = new T(parent);
  dialog->setModal(false);
  dialog->show();
  dialog->setAttribute(Qt::WA_DeleteOnClose);
  QObject::connect(dialog, &QDialog::finished, [dialog, f = std::move(fun)]{
    f(dialog);
  });
  return dialog;
}

Then, write:

void Class::myMethod() {
  show<MyDialog>(my_parent, [](QDialog *dialog){
    // do things when the dialog is finished
  });
}

instead of:

void Class::myMethod() {
  MyDialog dialog{my_parent};
  dialog.exec();
  // do things when the dialog is finished
}
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313