How to prevent QML events to happen after QCoreApplication::aboutToQuit or make sure a C++ function will be last?
-
Hi,
I'm having a main cpp instance Qrop which is aQObject
and a singleton.
in themain.cpp
, I'm connectingQCoreApplication::aboutToQuit
to its destruction (cf here)
My mainqrop
cpp object and some of its members are used in QML making sure their ownership (deletion) is made in C++.The main methods looks like this:
int main(int argc, char *argv[]) ... Qrop *qrop = Qrop::instance(); QObject::connect(&app, &QCoreApplication::aboutToQuit, &Qrop::clear); int res = qrop->init(); if (res != 0) return res; FamilyService *svcFamily = qrop->familyService(); QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("cppQrop", qrop); engine.rootContext()->setContextProperty("cppFamily", svcFamily); // really important, otherwise QML could take ownership and delete them // (cf http://doc.qt.io/qt-5/qtqml-cppintegration-data.html#data-ownership ) engine.setObjectOwnership(qrop->buildInfo(), QQmlEngine::CppOwnership); engine.setObjectOwnership(qrop->news(), QQmlEngine::CppOwnership); engine.setObjectOwnership(svcFamily->modelFamily(), QQmlEngine::CppOwnership); engine.setObjectOwnership(svcFamily->modelSeedCompany(), QQmlEngine::CppOwnership); // QQmlFileSelector *selector = new QQmlFileSelector(&engine); const QUrl url(QStringLiteral("qrc:/qml/MainWindow.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); engine.addImageProvider("pictures", new QrpImageProvider()); if (qrop->hasErrors()) qrop->showErrors(); qrop->news()->fetchNews(); return QApplication::exec(); }
I've noticed the App is crashing when I close the Window due to a
currentIndexChanged
event on a Combobox happening after my C++ objects are destructed (so after theQCoreApplication::aboutToQuit
). The crash is simple, in the handler I'm using one of my deleted C++ objects... cf hereI've made a hack that is working to prevent the crash by emitting an
aboutToQuit
signal from my main Qrop object in its destructor (cf here) which is connected in QML Combobx (cf here) but I don't find this really pretty...Is there a way to make sure a C++ handler would be called last? meaning no more QML events?
What would be the regular way to do that? -
Instead of using Qrop as singleton in main.cpp - put it on stack, then it will get deleted when
main
gets out of scope. Or make QQmlEngine a parent of Qrop, then parent-child relationships will take care of the cleanup.You can continue using Qrop as singleton in other parts of the app, this is only about main.
-
Instead of using Qrop as singleton in main.cpp - put it on stack, then it will get deleted when
main
gets out of scope. Or make QQmlEngine a parent of Qrop, then parent-child relationships will take care of the cleanup.You can continue using Qrop as singleton in other parts of the app, this is only about main.
@sierdzio hum indeed easy... Thanks!
I've made the QML engine parent of my main C++ singleton and its working like expected \o/ (cf changes (ignore new cmd.cpp file))my first implementation of the singleton was using a static object on the stack and if I remember well it wasn't deleted. That is why I went for a heap solution and used that
QCoreApplication::aboutToQuit
connection to destroy it.