[Development] On QML, ownership, QObject-trees and QSharedPointer
Stephen Kelly
stephen.kelly at kdab.com
Thu May 24 21:57:40 CEST 2012
Hi Rene,
Thanks for the email. I think you raise some valid points. Some work on
addressing them is already underway.
On Wednesday, May 23, 2012 12:25:42 Rene Jensen wrote:
> Disclaimer 3: Discussing QML seems very poisonous these days, but I
> still feel the need for a thread that focus on the good and bad with
> the current design and/or the current documentation specifically
> regarding exposing C++ to QML. Hopefully you agree and can accept that
> I bring it up on the developer list.
Yes, I think this email has the right tone and content, as others have said
too.
>From the forum:
> Can QML gracefully handle pointers wrapped in QSharedPointer?
The answer is not yet - maybe in Qt 5.1.
>
> So rewording the concerns to open up for (hopefully) useful comments -
> I can perhaps try to make a wiki article which adds any missing
> information:
>
> OWNERSHIP...
>
> These are the ownership "universes" (unless I'm mistaken):
>
> 1) Objects created in C++ owned via the QObject parent/child tree
> e.g.: new MyGizmo.
> 2) Objects created in C++ owned via the QSharedPointer system, e.g.:
> QSharedPointer (new MyGizmo).
> 3) Objects created by QDeclarativeEngine or Javascript owned by the
> engine, e.g.: MyGizmo { ... properties ... }
Looks right to me.
>
> Question: How can we expose objects governed by QSharedPointer to QML
> safely? I *can* guarantee the lifecycle beyond the life of my
> QDeclarativeEngine.
If you can guarantee that, then use mySharedPtr.data() as others have said.
>
> These are the ways to transfer values/references from C++ to QML
> (let's ignore the other way around for now):
>
> A) By calling QDeclarative::setRootContext (ownership not transferred:
> http://qt-project.org/doc/qt-4.8/qdeclarativecontext.html#setContextProperty
I think it's more common to use
QDeclarativeEngine::rootContext()->setContextProperty()
as Alberto said.
> D) By QML accessing a Q_PROPERTY on a C++ object (ownership?).
I guess you mean a binding?
> I assume that each time a value crosses a boundary between from C++ =>
> QML => Javascript an automatic conversion takes place. This conversion
> is probably the root of all evils, since a lot can happen with pointer
> references being smashed to either some form of null (as in
> unsuccessful C++ to QML assignment via (A) or (B) above) or
> "undefined" (like when a javascript expression tries to access a QML
> Component property) depending on factors not quite clear to me.
>
> Question: What are the exact mechanisms that governs value conversion
> from one space to another?
Beyond what Christopher said, there's some more automation possible. We can
add QSharedPointer<QObjectDerived> awareness to QML, as long as doing:
if (we_know_variant_contains_a_QSharedPointer_To_QObjectDerived) {
QSharedPointer<QObject> sp;
sp = *reinterpret_cast<QSharedPointer<QObject>*>(variant.data());
}
...is ok, which I think it is. However, we'll more likely want to make that
possible with QWeakPointer based instances (otherwise declarative might store
our QSharedPointer and not drop its refcount - it's a tricky issue), which
should also be possible.
After this patch:
https://codereview.qt-project.org/#change,27070
we_know_variant_contains_a_QSharedPointer_To_QObjectDerived
will be:
QMetaType::typeFlags(variant.userType()) & QMetaType::SharedPointerToQObject
or similar. We would be able to handle
Q_PROPERTY(QSharedPointer<QObjectDerived> ...) too.
After this stuff:
https://codereview.qt-project.org/#change,27071
... and a few more tricks adding function pointers to the QVariant::Handler,
we would be able to handle Q_PROPERTY(QSharedPointer<SomeType> ...) too.
This is the kind of integration that I wish had been thought of for
declarative use-cases long ago and designed into QVariant in Qt 5 with the
hybrid QML application use-cases in mind.
The needs QtDeclarative has needs for non-type-safety and conversions are
mostly separate and internal, so it's not as easy as it could be to use user-
defined types and containers and QVariants with QML, like automatic handling
of QList<int>, QVector<int> and generally Container<T>. Maybe we can make this
stuff better in 5.1 though... We'll have to see if it works and the API can be
extended for it in a maintainable way.
Handling QObject derived types might be easily handled too (currently it
introduces several inconveniences for hybrid apps):
https://codereview.qt-project.org/#change,13006
https://codereview.qt-project.org/#change,13007
https://codereview.qt-project.org/#change,19113
>
> COLLECTIONS...
>
> Collections (QList, QMap, QHash, QSet) of object references
> constitutes a special scenario which in my view is less that ideally
> solved. I would love a much simpler and more intuitive way to expose
> those to QML. But given that this topic is way too large, I don't want
> to bring it up here, although it does belong.
I have a working patch , but again, it was already pushed back to 5.1:
https://bugreports.qt-project.org/browse/QTBUG-23566
I'm still not 100% certain if this stuff can be done correctly and efficiently
in 5.1, so that's why I've said 'maybe' so many times in this mail :). Another
reason for the 'maybe's is that maybe we'll find that my plans and ideas are
no good.
Thanks,
--
Stephen Kelly <stephen.kelly at kdab.com> | Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
www.kdab.com || Germany +49-30-521325470 || Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-Independent Software Solutions
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.qt-project.org/pipermail/development/attachments/20120524/fa1aeb43/attachment.sig>
More information about the Development
mailing list