[Development] On QML, ownership, QObject-trees and QSharedPointer

Rene Jensen rene at catatonic.dk
Wed May 23 12:25:42 CEST 2012


Hello qtpies.

Disclaimer 1: I have read incessantly in the Quick documents, searched
the net and also extensively used QML. Please don't LMGTFY or RTFM me
instinctively ;-)
Disclaimer 2: I started a topic at QtCentre
(http://www.qtcentre.org/threads/49059-QSharedPointer-QWeakPointer-in-QML),
hoping to open up a larger discussion about the handling of objects
and types between C++ and QML, but I have closed down that broader
topic and moved it to this list instead.
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.

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 ... }

Question: How can we expose objects governed by QSharedPointer to QML
safely? I *can* guarantee the lifecycle beyond the life of my
QDeclarativeEngine.

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).
B) By calling QObject::setProperty on the instantiated component (ownership?)
C) By QML calling a method on a C++ object and getting a response
(ownership IS transferred to QML. In the docs somewhere.)
D) By QML accessing a Q_PROPERTY on a C++ object (ownership?).

Now, A+B lend themselves badly as mechanisms to expose subobjects, but
makes it easy to specify ownership via
QDeclarativeEngine::setObjectOwnership.
Conversely C+D are better at exposing subobjects or related
collections (in QML... myProperty: myGizmo.findAllTimelineEvents() ),
but I don't see how I can specify ownership in a QML-agnostic way (C++
models should not know about QML!)

Question: What happens to ownership in each of these transfers?

TYPESYSTEM...

Then there is the issue of what type is associated with the object.
This is relevant when specifying properties in QML. I believe that a
major source of confusion comes from the notion that there are three
type systems involved:

1) The traditional Qt/C++ moc/compiler types (perhaps QObjects,
perhaps declared Q_DECLARE_METATYPE to make QVariant understand them)
2) The types that the Javascript engine knows (Object, Function,
Number, String etc.)
3) The types that the QML engine understands
(http://doc-snapshot.qt-project.org/4.8/qdeclarativebasictypes.html
plus those registered with qmlRegisterType). QVariants can be used
too.

Question: Are there 2 or 3 typesystems?

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?

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.

DOCUMENTATION...

The truth is that initially in ten out of ten cases I resorted to
guessing about the type and ownership of a value when I cross a
boundary. Since I have thoroughly cross examined the docs, it must
mean that (subjectively) I find it hard to extract the proper
information from them. I miss clear best practices, and often feel
more confused by reading the docs than I feel enlightened. In fact,
let me upgrade that statement:

We are quite a lot of programmers who do not have the luxury of
reading long passages of prose in documentation anymore! (For the same
reason I have avoided writing this email as long as I could to spare
*you* the burden of reading messy prose text). We need quick reference
cards containing COMPLETE information about all possibilities in one
place. You are only asking for trouble if you make it mandatory to
read every article under
http://doc-snapshot.qt-project.org/4.8/qtquick.html to be able to
write bug free code.
Sorry. But I'm learning a new technology just about every week - most
in vain. I get my dose of documentation, thank you.

Hoping for an enriching debate,

Best regards,
Rene Jensen



More information about the Development mailing list