Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Proper way of closing an application



  • Hello,

    I'm writing a small program to communicate with Bluetooth devices.

    So far it is working fine and I am trying to fix some minor details:

    I want to delay the closing of the app to give it time to disconnect from all devices:

    1. Right now I am overriding the internal onClose(QCloseEvent *event) function to event->ignore() the close-event and handle my own code.

    2. So this part is working fine, right now I am having an issue to call the close-event manually as soon as my code has finished.

    3. I tried QApplication::quit(), which stopped my program and closed all windows, however I feel like there is something wrong, because it leaves an icon of the app in the system-tray.

    4. That definitely doesn't happen when I use the proper event->accept() in the onClose(*) function.

    Any hints on how to delay and close the app manually are very appreciated!

    Thanks



  • Hello!

    You do not have to override the onClose event. I suggest you to to read this doc (https://doc.qt.io/qt-5/qapplication.html):

    We recommend that you connect clean-up code to the aboutToQuit() signal, instead of putting it in your application's main() function. This is because, on some platforms the QApplication::exec() call may not return. For example, on the Windows platform, when the user logs off, the system terminates the process after Qt closes all top-level windows. Hence, there is no guarantee that the application will have time to exit its event loop and execute code at the end of the main() function, after the QApplication::exec() call.

    Example:

    connect(QApplication::instance(), &QApplication::aboutToQuit, this, [this]() {
        //Your clean-up code
    });
    

    So, you have to use aboutToQuit signal (https://doc.qt.io/qt-5/qcoreapplication.html#aboutToQuit) to clean up your app resources before exiting. As for the app icon (QSystemTrayIcon) in the tray, you must deal with it separately. You can use the hide method (https://doc.qt.io/qt-5/qsystemtrayicon.html#hide) when aboutToQuit signal occurs. Also, keep in mind if QSystemTrayIcon is initialized as a pointer, you should call deleteLater() method after hide there as well. Happy coding!



  • @Cobra91151
    The problem here is that aboutToQuit() will return when the slot code returns. The way @unzu describes his situation with

    I want to delay the closing of the app to give it time to disconnect from all devices:

    makes me think he needs to give time for the clean up to complete, and he wants to do this asynchronously, not blocking. Is that the case?



  • @Cobra91151 said in Proper way of closing an application:

    Also, keep in mind if QSystemTrayIcon is initialized as a pointer, you should call deleteLater() method after hide there as well.

    I never coded that icon, its just a black slot in the tray.
    I think its generated automatically by the MainWindow.

    @JonB said in Proper way of closing an application:

    makes me think he needs to give time for the clean up to complete, and he wants to do this asynchronously, not blocking. Is that the case?

    Yes, that is the case.
    If possible I need to ignore the QCloseEvent, do my stuff, and fire another QCloseEvent.
    I just don't know how to fire that, its generated by clicking the red X (close) button of the MainWindow.

    I hoped there would be a way to generate that event via code and let Qt handle the hidden stuff.



  • @unzu
    You don't "generate the event via code", you just call close() on the object.



  • @JonB said in Proper way of closing an application:

    You don't "generate the event via code", you just call close() on the object.

    Thanks!

    I am calling close() now, I like that quite a bit more than the QApplication::quit().


Log in to reply