Shared Pointers and QML Ownership
En Ar Bg De El Es Fa Fi Fr Hi Hu It Ja Kn Ko Ms Nl Pl Pt Ru Sq Th Tr Uk Zh
- 1 Handling of objects and types between C++ and QML
Handling of objects and types between C++ and QML
- Summarized from: http://lists.qt-project.org/pipermail/development/2012-May/004049.html
- Added by sivang
- Discussion started in an attempt to understand how objects are owned and are made available to QML through C+, and their maintenance thereafter.
Q: How can we expose objects governed by QSharedPointer to QML safely? (Assume that we are talking about a pointer to a QObject)
bq. Currently, QML isn't aware of QSharedPointer and friends, but internally uses its own guard-types to react to QObject deletion. If you want to ensure that the engine won't delete the QObject you pass in, you need to explicitly set the ownership of the QObject to CppOwnership (there's a QQmlEngine function to do so). Alternatively, if the QObject has a parent (ownership parent) set, the engine won't delete it.
A: You need to observe these rules:
- You need to be able to guarantee the life of your QObject beyond the life of the QDeclarativeEngine. [ Reason: It was suggested in the mailing-list thread that the engine could cache a reference to the object ]
- It is too dangerous to mix QSharedPointer ownership with the QObject parent/child ownership.
- [ Should the referenced class inherit QObject? ]
Thus this is the only way to go about it:
- Call doc:QSharedPointer :: data() to get a pointer to the referenced class;
- Make sure the QML engine doesn't assume ownership: doc:QDeclarativeEngine :: setObjectOwnership (P). This step is necessary since the only other way of keeping the engine from assuming ownership would be to give the object a parent, which is out of the question since the shared pointer already has ownership.
- Hand over the raw QObject pointer to QML using either doc:QObject :: setProperty or doc:QDeclarativeContext :: setContextProperty
Ways of exposing references to QML and their effect on ownership
- The QML engine respects normal QObject parenting.
- By calling QDeclarative::setRootContext (ownership not transferred: http://doc.qt.io/qt-4.8/qdeclarativecontext.html#setContextProperty).
' no ownership change.
- By calling QObject::setProperty on the instantiated component (ownership?)
' no ownership change
- By QML calling a method on a C+ object and getting a response (ownership IS transferred to QML if and only if the QObject has no parent)
- By QML accessing a Q_PROPERTY on a C++ object (ownership?).
' no ownership change
Issues arising from type handling of objects exposed; relevant when specifying properties in QML
Crossing C++ / QML boundaries issues.
Special semantics for null and undefined
- if "undefined" is assigned to a QVariant property which is Reset-able, we reset the property.
- Null is generally treated as a null-ptr when assigned to QObject-derived-type properties, but otherwise may fail, depending on the property type.
Improvements in the works (Qt5)
- Simpler and more intuitive way to expose Collections (QList, QMap, QHash, QSet) to QML:
At the moment, QList of int, bool, qreal, QString, QUrl.