Qt 6: can't create working local QEventLoop while handling aboutToQuit()
-
My application needs to respond to the
QCoreApplication::aboutToQuit()
signal by chatting with some background worker threads. It's not just waiting for them to finish — they need to "chat" back and forth with the main thread, the way it's written.My understanding has been that I should program the main thread's
aboutToQuit()
handler so that it doesn't return until all threads are ready to be killed.Under Qt 5.15.2, I was able to do that in my handler by spinning a local
QEventLoop
or callingprocessEvents()
repeatedly (as documented) until all background threads are finished chatting with the main thread using the signal/slot connections they have built.Under Qt 6.5.3, apparently due to changes in the way
aboutToQuit()
is administered inqcoreapplication.cpp
, this no longer works. The localQEventLoop
'sexec()
call returns immediately because the main thread'squitNow
flag has already been set, where previously it was not set at the time of this signal.What is the "new" correct way to forestall the app shutdown if my app still needs to pass events between threads?
PS edit: This is a QML application.
-
Hi, maybe try QWindow's closeEvent and set accepted to false, or on the C++ side the closeEvent()?
In C++, say like this:
... void MainWindow::closeEvent(QCloseEvent *event) { static bool bThreadsDone = false; if (!bThreadsDone) { event->ignore(); QTimer::singleShot(1234,[&bThreadsDone] { // check if threads are done (assuming yes :-) bThreadsDone = true; qApp->quit(); }); } ... }
When the user quits the app, in the above example, there will be a delay of 1234 milliseconds before the app exits.
@hskoglund I think this may be the only way to go, especially if the result of the thread interaction requires any sort of GUI (posting error messages, etc.). It does seem that
aboutToQuit()
is too late in the sequence.Evidence, after some exploration:
- My problem was caused by a change in Qt 6.5.0 (link) that moved the signaling point from
QCoreApplication::execCleanup()
(which explicitly turns off thequitNow
flag) toexit()
(which doesn't). That flag is what prevents a localQEventLoop
in my slot handler from spinning up. It's not clear if they meant to do that, but... - That change refers to a bug report (link). A comment by the maintainer says, "The docs for aboutToQuit specify 'Note that no user interaction is possible in this state.'"
- And indeed they do (link).
- My problem was caused by a change in Qt 6.5.0 (link) that moved the signaling point from
-
Hi, maybe try QWindow's closeEvent and set accepted to false, or on the C++ side the closeEvent()?
In C++, say like this:
... void MainWindow::closeEvent(QCloseEvent *event) { static bool bThreadsDone = false; if (!bThreadsDone) { event->ignore(); QTimer::singleShot(1234,[&bThreadsDone] { // check if threads are done (assuming yes :-) bThreadsDone = true; qApp->quit(); }); } ... }
When the user quits the app, in the above example, there will be a delay of 1234 milliseconds before the app exits.
-
Hi, maybe try QWindow's closeEvent and set accepted to false, or on the C++ side the closeEvent()?
In C++, say like this:
... void MainWindow::closeEvent(QCloseEvent *event) { static bool bThreadsDone = false; if (!bThreadsDone) { event->ignore(); QTimer::singleShot(1234,[&bThreadsDone] { // check if threads are done (assuming yes :-) bThreadsDone = true; qApp->quit(); }); } ... }
When the user quits the app, in the above example, there will be a delay of 1234 milliseconds before the app exits.
@hskoglund I think this may be the only way to go, especially if the result of the thread interaction requires any sort of GUI (posting error messages, etc.). It does seem that
aboutToQuit()
is too late in the sequence.Evidence, after some exploration:
- My problem was caused by a change in Qt 6.5.0 (link) that moved the signaling point from
QCoreApplication::execCleanup()
(which explicitly turns off thequitNow
flag) toexit()
(which doesn't). That flag is what prevents a localQEventLoop
in my slot handler from spinning up. It's not clear if they meant to do that, but... - That change refers to a bug report (link). A comment by the maintainer says, "The docs for aboutToQuit specify 'Note that no user interaction is possible in this state.'"
- And indeed they do (link).
- My problem was caused by a change in Qt 6.5.0 (link) that moved the signaling point from
-