PDA

View Full Version : Properly ending background tasks on qApp->quit()



matt4682
1st April 2015, 19:46
When closing a program, it runs the following code block



connect(ui->actionExit, &QAction::triggered, [&]() {
QSettings s;
s.setValue("mainWindowGeometry", saveGeometry());
s.setValue("mainWindowState", saveState());

qApp->quit();
});


but sometimes the application will still hang around in the background and I have to kill it through task manager.
I suspect that this is related to various QtConcurrent::run() and QEventLoop::exec() calls. If I use exit(0) or qApp->exit(0) rather than qApp->quit() the application seems to exit more frequently but it still ends up hanging.

Is there a better way to approach exiting an application that will prevent it from hanging around in the background?

wysota
1st April 2015, 20:18
All quit() does is that it exits the event loop. I believe it should exit all QEventLoop::exec() calls too, so that shouldn't be a problem. As for Qt Concurrent, you probably have some registry of scheduled tasks so you can prevent quitting the event loop before all of them are finished or you can cancel them before you quit.

matt4682
1st April 2015, 23:19
Aha, I started keeping a registry by appending the returns of QtConcurrent::run() to a QList<QFuture<void>> then when I try to exit out of the program I can just do



for(QFuture<void> f : this->registry) {
if(f.isRunning()) {
qApp->processEvents();
f.waitForFinished();
}
}

Before the application calls qApp->quit().
Since the QFutures were made from QtConcurrent::run() they can't be cancelled so I just set a bool to signal the running functions to finish up

anda_skoa
2nd April 2015, 09:00
Just a general remark: it is often more appropriate to do that window geometry saving in the window's closeEvent() handler and have the exit/quit action connected to the window's close() slot.

That way the saving is also invoked if the window is closed through the windowing system, e.g. the user clicking the window decoration's X button, ALT-F4, the user closing the window through context menu of the taskbar, etc.

Cheers,
_

matt4682
2nd April 2015, 22:55
Just a general remark: it is often more appropriate to do that window geometry saving in the window's closeEvent() handler and have the exit/quit action connected to the window's close() slot.

That way the saving is also invoked if the window is closed through the windowing system, e.g. the user clicking the window decoration's X button, ALT-F4, the user closing the window through context menu of the taskbar, etc.

Cheers,
_

The application has a close to tray setting so more often than not, the close event is ignored.
I ended up moving the entire exit procedure into its' own method and it's called from various places in the program now (tray icon exit, menu exit and window close if close to tray is disabled).