Passing objects from C++ to QML



  • I am having trouble understanding how objects in QML work. I see that it's possible to register a QObject subclass so that QML can make instances of it, but is it possible to make an instance of a QObject in C++ and pass it to QML? If so, how can signal handlers be connected to it, and how is the memory managed?

    This is the example I tried, but it fails with this error message:

    QMetaObject::invokeMethod: No such method
    QQuickWindowQmlImpl_QML_0::myCallback(QObject*)
    Candidates are:
        myCallback(QVariant)
    

    This is the C++ code:

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    QObject *rootObj = engine.rootObjects().at(0);
    QObject *myObj = new QObject();
    myObj->setProperty("myStringProperty", "asdfasdf");
    QMetaObject::invokeMethod(rootObj, "myCallback", Q_ARG(QObject*, myObj));
    

    And the QML code:

    import QtQuick 2.4
    import QtQuick.Window 2.2
    Window {
        visible: true
        Rectangle {
            id: root
            anchors.fill: parent
            color: "gray"
            Text {
                id: label
                anchors.centerIn: parent
                text: "(waiting for callback)"
            }
        }
        function myCallback(obj) {
            label.text = obj.myStringProperty
        }
    }
    

    When I try replacing QObject* with QVariant in the Q_ARG, that causes a C++ compiler error.

    If this is not possible, then how else can a QML user interface be made aware of dynamically added and removed entities in the C++ code, each with some properties and events associated with them, which need a representation in the UI?


  • Moderators

    Hi @MTK358,

    is it possible to make an instance of a QObject in C++ and pass it to QML? If so, how can signal handlers be connected to it

    Yes. Set your C++ QObject as a Context Property: http://doc.qt.io/qt-5/qtqml-cppintegration-contextproperties.html

    That link also shows you how to make connections.

    and how is the memory managed?

    Your C++ code remains responsible for deleting that QObject: http://doc.qt.io/qt-5/qqmlcontext.html#setContextProperty



  • @JKSH said:

    Yes. Set your C++ QObject as a Context Property: http://doc.qt.io/qt-5/qtqml-cppintegration-contextproperties.html

    That link also shows you how to make connections.

    Thank you, that's what I was looking for.

    Your C++ code remains responsible for deleting that QObject: http://doc.qt.io/qt-5/qqmlcontext.html#setContextProperty

    What if QML connects to a signal of a context property object, that signal has a QObject* as an argument, and the JS handler code saves it in some item's property?

    Will deleting it cause a segfault in the QML interpreter? Is there a way to know that it's not referenced any more?


Log in to reply
 

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