How to prevent a modal QDialog from being hidden or close after calling exec.
-
Hello everyone,
I am having a problem I cannot find a proper solution for.
I am writing code which requires a control and if it fails, I want to display a blocking QDialog which asks the end-user of he wants to retry or cancel the operation.
The dialog is customized because it has to display a lot of information but it has the behavior of a QMessageBox with Accept and Reject
So I call QDialog::exec and whether the QDialog is rejected or accepted, I cancel or retry the operation.My problem is that I would like to prevent the QDialog from disappearing when I retry the operation and avoid a sequence of 'kill the pop-up' dialog if the retry fails.
I would like to manage the QDialog myself with reject.The calling code is
class MyErrorDialog : public QDialog { }; MyErrorDialog* error_dialog = nullptr; bool retry = false; do { if( control() ) { // Success if( error_dialog != nullptr ) { // Dismiss the error dialog if it has been displayed previously error_dialog->reject(); return true; } retry = error_dialog->exec() == QDialog::Accepted; } while( retry == true ); // User cancelled the operation so we can dismiss the dialog error_dialog->reject(); return false; }The MyErrorDialog has 2 QCommandLink button, the retry one connected to accept, the cancel one connected to reject and they trigger the proper results.
I tried overriding QDialog::hideEvent or QDialog::closeEvent but after exec, MyErrorDialog always disappearIs my idea possible or am I making a mistake by trying to call multiple time exec on the same dialog? Once exec is finished, the local event loop is dead so I cannot keep my error dialog alive.
I cannot easily move the logic of control in a QDialog::accept. That would simplify things: I would just have to override QDialog::accept and test the control thereThank you in advance.
Didier
-
Hello everyone,
I am having a problem I cannot find a proper solution for.
I am writing code which requires a control and if it fails, I want to display a blocking QDialog which asks the end-user of he wants to retry or cancel the operation.
The dialog is customized because it has to display a lot of information but it has the behavior of a QMessageBox with Accept and Reject
So I call QDialog::exec and whether the QDialog is rejected or accepted, I cancel or retry the operation.My problem is that I would like to prevent the QDialog from disappearing when I retry the operation and avoid a sequence of 'kill the pop-up' dialog if the retry fails.
I would like to manage the QDialog myself with reject.The calling code is
class MyErrorDialog : public QDialog { }; MyErrorDialog* error_dialog = nullptr; bool retry = false; do { if( control() ) { // Success if( error_dialog != nullptr ) { // Dismiss the error dialog if it has been displayed previously error_dialog->reject(); return true; } retry = error_dialog->exec() == QDialog::Accepted; } while( retry == true ); // User cancelled the operation so we can dismiss the dialog error_dialog->reject(); return false; }The MyErrorDialog has 2 QCommandLink button, the retry one connected to accept, the cancel one connected to reject and they trigger the proper results.
I tried overriding QDialog::hideEvent or QDialog::closeEvent but after exec, MyErrorDialog always disappearIs my idea possible or am I making a mistake by trying to call multiple time exec on the same dialog? Once exec is finished, the local event loop is dead so I cannot keep my error dialog alive.
I cannot easily move the logic of control in a QDialog::accept. That would simplify things: I would just have to override QDialog::accept and test the control thereThank you in advance.
Didier
@Didier-Donner
I'm sorry I haven't followed the detail of what you are asking for. But QDialog::exec() is intended to destroy and exit, and read what it says there. If you want to keep the dialog around and manage it yourself use QDialog::open(). -
Hi,
@JonB nothing wrong with calling exec multiple time, it's just blocking slot with the caveat of the internal loop. However I do agree that open is likely the better tool here.
@Didier-Donner As for keeping the dialog alive, you should then use your own signal as you neither want to accept nor reject. Both are "closing" actions. So they don't fit your architecture.
-
Hi,
@JonB nothing wrong with calling exec multiple time, it's just blocking slot with the caveat of the internal loop. However I do agree that open is likely the better tool here.
@Didier-Donner As for keeping the dialog alive, you should then use your own signal as you neither want to accept nor reject. Both are "closing" actions. So they don't fit your architecture.
@SGaist said in How to prevent a modal QDialog from being hidden or close after calling exec.:
@JonB nothing wrong with calling exec multiple time, it's just blocking slot with the caveat of the internal loop. However I do agree that open is likely the better tool here.
I thought OP was calling
exec()once but wanted control the dialog so it did not exit or it retried or something, he keeps saying he wants to keep it alive. But maybe not :)As for pattern, I thought putting up another modal dialog when you have one on the go was "frowned upon" for end users. But again maybe not :)
-
Without dissecting the above...don't create it as a modal dialog. Make it modeless and manually manage display/hide state for the best control of what's going on.
-
Hello everyone,
I realized that my idea could not work with my current architecture. I need to shift the validation to the dialog by override QDialog::accept. This way, I can keep my dialog visible, provide the end-user some feedback in case the retry fails.
I would have preferred to keep the UI and the backend separated but that cannot be the case so be itThank you all for your answers. Take care
Didier
-
Hello everyone,
I realized that my idea could not work with my current architecture. I need to shift the validation to the dialog by override QDialog::accept. This way, I can keep my dialog visible, provide the end-user some feedback in case the retry fails.
I would have preferred to keep the UI and the backend separated but that cannot be the case so be itThank you all for your answers. Take care
Didier
@Didier-Donner said in How to prevent a modal QDialog from being hidden or close after calling exec.:
I need to shift the validation to the dialog by override QDialog::accept. This way, I can keep my dialog visible, provide the end-user some feedback in case the retry fails.
I would have preferred to keep the UI and the backend separated but that cannot be the case so be itNow I understand. You could still probably do it per my suggestion of using
QDialog::open()instead ofexec(), since you then control when to close the dialog and can not do so on validation failure.However, if you wish to do the validation inside the dialog prior to
accept()from withinexec()you can do that. You can still keep the UI and the backend separate by, for example, providing a small contract class which is virtual/abstract. That would provide one (pure) virtual method likevirtual bool isValid(...) const = 0;. The dialog exports this abstract class and callsisValid(...)to decide what to do. The caller provides a concrete implementation of the abstract class withisValid(...)taking some parameter for the backend implementation to examine. This is a common paradigm and more or less keeps UI and backend separated.