Calling JS functions in loaded components from C++



  • Hi
    i have main.qml file that it have one JS function in it, i can call the function from C++ by "Q_INVOKABLE" and "QMetaObject::invokeMethod", also i have another Qml file "MyFile.qml" that loaded into "main.qml" with this code:

                var component = Qt.createComponent("file:MyFile.qml");
                var object  = component.createObject(container, {"x": 0, "y": 0});
    

    i cant call functions in MyFile.qml from C++.

    auto root_object = engine->rootObj().first();
    QMetaObject::invokeMethod(rootObj,"jsFunc",Q_RETURN_ARG(QVariant,retVal),Q_ARG(QVariant,conObj));
    

    Error: QMetaObject::invokeMethod: No such method QQuickWindowQmlImpl_QML_35::jsFunc(QVariant)

    pls help

    Thanks in advance


  • Moderators

    @Alper said:

    auto root_object = engine->rootObj().first();
    QMetaObject::invokeMethod(rootObj,"jsFunc",Q_RETURN_ARG(QVariant,retVal),Q_ARG(QVariant,conObj));
    

    You're trying to call a function named "jsFunc" that is part of root_object (e.g. your ApplicationWindow) but what you want to do is calling a function of an object that is a child of root_object.

    So first, you need to find the child in the hierarchy and then you can call one of its functions. The easiest way to find children is by giving them a unique objectName in QML, like:

    var object  = component.createObject(mainWindow, {"objectName":"someIdentifier"} );
    

    Then, in C++, you can do this:

    QQuickItem *someItem = m_engine->rootObjects().first()->findChild<QQuickItem*>("someIdentifier");
    QMetaObject::invokeMethod(someItem,"jsFunc");
    


  • @Wieland said:

    mainWindow

    Thanks for your answer.
    So i wrote exactly:

    var object  = component.createObject(container, {"objectName":"someIdentifier"} );
    

    and in C++ i did exactly: (it is after loading component into main window)

    QQuickItem *someItem = m_engine->rootObjects().first()->findChild<QQuickItem*>("someIdentifier");
    QMetaObject::invokeMethod(someItem,"jsFunc");
    

    but it not works.
    Have i replace another thing instead of "objectName" or "someIdentifier" ??


  • Moderators

    Hi @Alper
    Have you made sure that the exact object is found ?
    What does qDebug() << someItem print ? It should print the objectName someIdentifier with some other properties.



  • @Wieland
    i solved it!
    i just added a line in MyFile.qml like this:

    Item {
        objectName: "comId"
    ...
    

    main .qml:

    var object  = component.createObject(scr, {"comId":"someId"} );
    

    C++ side:

      QObject *someItem = m_engine->rootObjects().first()->findChild<QObject*>("comId");
      QMetaObject::invokeMethod(someItem,"jsFunc");
    

    Thanks for your help.


  • Moderators

    @Alper Good :)
    But following line doesnot make any sense:
    var object = component.createObject(scr, {"comId":"someId"} );

    You are trying to assign someId to a property named comId which is not present.
    The fact that it worked was due to objectName: "comId" in MyFile.qml which was actually referred when you called findChild.



  • @p3c0

    yes thank you
    it works with:
    var object = component.createObject(scr);
    so can i set dynamic objectName property to component?

    this worked:

    var object  = component.createObject(scr,{"objectName": "newName"});
    

  • Moderators

    @Alper

    so can i set dynamic objectName property to component?

    Yes. @Wieland's suggestion was correct.
    It seems that you passed the wrong parent earlier.


Log in to reply
 

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