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*
withQVariant
in theQ_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?
-
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?
-
There are several ways how to communicate between C++ and QML. The most important part is to set up your class with signals and slots to be used in QML.
A simple guide with an example project can be found here:
https://v-play.net/cross-platform-development/how-to-expose-a-qt-cpp-class-with-signals-and-slots-to-qml#how-to-communicate-between-cpp-and-qml