How to execute C++ code when QML initialization is complete?



  • I am trying to connect a QML signal to a C++ slot when my application starts. I am trying to use the following snippet of code to do this:

    QQmlApplicationEngine *qqae = (QQmlApplicationEngine*)qmlEngine(this);
    QObject *item = qqae->rootObjects().first()->findChild<QObject *>("calibrationTabItem");
    if (item == nullptr)
    {
        qDebug() <<"calibrationTabItem not found";
    }
    connect(item, SIGNAL(performOffsetCalibration),
            this, SLOT(PerformOffsetCalibration));
    

    This code is executed in the Component.onCompleted of a custom type created with qmlRegisterType. The problem is that the list returned by rootObjects() is empty. It seems odd that the rootObjects list is empty during an onCompleted call.

    I have tried executing the same code in a button onClicked handler, just as a way of running it after all initialization is complete. In that case the list of rootObjects is not empty and the code works correctly.

    How can I connect this code to a function/signal that happens after all the QML code is initialized?



  • Hi! completed is emited when the QML engine created the object / added it to the object tree. It doesn't say anything about the current state of its potential child objects or attached objected. I personally find the following approach for integrating C++ and QML much nicer: https://forum.qt.io/post/354757



  • @Steve-Fallows said in How to execute C++ code when QML initialization is complete?:

    I am trying to connect a QML signal to a C++ slot when my application starts. I am trying to use the following snippet of code to do this:

    QQmlApplicationEngine *qqae = (QQmlApplicationEngine*)qmlEngine(this);
    QObject *item = qqae->rootObjects().first()->findChild<QObject *>("calibrationTabItem");
    if (item == nullptr)
    {
        qDebug() <<"calibrationTabItem not found";
    }
    connect(item, SIGNAL(performOffsetCalibration),
            this, SLOT(PerformOffsetCalibration));
    

    This code is executed in the Component.onCompleted of a custom type created with qmlRegisterType. The problem is that the list returned by rootObjects() is empty. It seems odd that the rootObjects list is empty during an onCompleted call.

    I have tried executing the same code in a button onClicked handler, just as a way of running it after all initialization is complete. In that case the list of rootObjects is not empty and the code works correctly.

    That's expected. Objects are added to the rootObjects list after their initialization completes. Parent objects only complete after all of their statically instantiated children. Presumably the custom object is a child of a root object, in which case the custom object must finish initialization prior to the parent.

    How can I connect this code to a function/signal that happens after all the QML code is initialized?

    The backend strategy @Wieland pointed out is one option.

    Another choice is to use the QQmlApplicationEngine::objectCreated signal and wait for the root item or calibrationTabItem to complete. The code that connects the signals should check to see if the root item is already complete, for the sake of handling dynamic object creation.



  • @Steve-Fallows I'd follow the approach suggested by @Wieland since it looks like a good idea, as also suggested to this question in stackoverflow



  • Hi, could you share a snippet of code from QML file?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.