Reputation: 8167
Under Qt5, how to wait until the main event loop has executed all slots that are connected to a specific widget?
Specifically, in the following example
class MyWidget : public QWidget {
~MyWidget() {
action_A();
}
void myclose() {
...
close();
}
};
...
auto* w = new MyWidget;
...
w->close();
action_B();
...
I want the two functions
action_A();
action_B();
to be executed in the above order. However, without further precaution, they are executed in the reverse order.
QWidget::close()
emits a signal which ultimately triggers deletion of the MyWidget
instance. However, to the best of my understanding, this will only happen after control has returned to the main event loop. In any case, it will not happen before we call action_B()
.
Related discussions that don't help:
QDialog
, accepted answer advises to use QDialog::exec()
. However, the Qt5 docs recommend to avoid QDialog::exec()
in favor of QDialog::open()
. For this and for other reasons I cannot avoid the call to QDialog::close()
.QDialog::exec()
.Upvotes: 1
Views: 1185
Reputation: 37707
Why do you think action_A()
and action_B()
should be called in this order?
Once the destructor is called, QObject
will no longer receive any new signals (except those emitted during d-tor execution), since it will not exist and all signals and slots will be disconnected.
Since action_A()
is a called from the destructor and action_B()
not, action_A()
is executed as last.
Note that close
may (doesn't have to) call deleteLater
to destroy the window and this thing schedules destruction of object in event loop.
Upvotes: 0
Reputation: 4367
Simply connect MyWidget
's destroyed()
signal to action_B
(or something that calls it). Since action_A
is called from MyWidget
's destructor, it will be called before the destroyed()
signal is emitted in ~QObject()
, and thus, action_B
called.
Note that you cannot control the timing of the call of action_A
as long as it from the destructor of MyWidget
, so deferring the call to action_B
is your only choice here, i.e. you cannot make w->close(); action_B();
work.
Upvotes: 2