QDeclarativeItem parent item, parent object and context
-
Trying to understand the relationship between the parent item (a QDeclarativeItem), the parent object (a QObject) and the context (a QDeclarativeContext) in which a QDeclarativeItem is created. And I cannot really find anything in the docs that fully describes this. Can anyone point me in the right direction?
What I need to understand is, when I create a QDeclarativeItem, when and to what should I set its parent item (setParentItem()) and parent object (setParent()) and what should be its context (passed to the QDeclarativeComponent::create() or QDeclarativeComponent::beginCreate() function).
-
The parent object (QObject) is the ownership. That is, when the parent is deleted, it will delete its children.
The parent item (QQuickItem) is the scene graph parent. This may be different in Qt4.x (QDeclarativeItem), but I presume it's analogous. So, it should define things like the bounding area and so forth. "Visual parent" might be another way to put it.
A QQmlContext (QDeclarativeContext in Qt4.x) contains information which allows symbols to be resolved and JavaScript code to be evaluated. A context owns the bindings of any object created in it, for example. The QQmlEngine (QDeclarativeEngine in Qt4.x) is basically a hierarchy of contexts, starting with the root context (which is the instantiation context for the root item of the root component).
To answer your question:
- the parent object should be whatever you want to own it
- the parent item shouldn't need to be set for an element in QML, since its parent item will be set automatically due to the declaration of its existence, but if you're creating it in C++ you might want to set it manually, I suppose.
- the creation context of a top level item should generally be the root context of an engine.
-
OK, thanks. That's pretty much what I figured out for myself from the docs, but nice to get it confirmed.
What we want to do is basically to create a hierarchy of QML elements dynamically from C++, that has the same behaviour and characteristics as it would have had if we had created it as static QML files. And it's still not totally clear to me how to do that, and how the QObject parent and context affect this.
If I want to get the same structure as I would get from static QML files, should the parent object be the same as the parent item, or should it be the engine / view?
And the context - does a statically loaded hierarchy of QML elements all share one context (the root context), or is there a hierarchy of contexts matching the hierarchy of elements?
-
You can get the context of an item by calling qmlContext() passing the item as an argument.
But in general, a hierarchy of QML elements will share one context, yes. We try to sparingly create contexts (eg, one for each separate evaluation context (script import, dynamically constructed component (with an ownContext), and so forth), and obviously different threads like in WorkerScript element).The top-level object of a QML hierarchy created via QQmlComponent::create() is (by default) an item with no parent and with CppOwnership explicitly set (that is, the caller takes ownership of it, and must delete it manually). All items in the hierarchy generally have their parent and parent item set to the same. There may be some exceptions here (eg, views and models etc may do things slightly differently, I don't recall), but certainly deleting the top-level object from C++ should cause all items to be deleted due to QObject ownership.
-
OK, excellent, thanks! Again, this is kind of what I though, but nice to get it confirmed.
The main reason we started looking into these things is that we were getting strange crashes when running in debug, and we thought we might have set some of these things up wrongly when building the QML element hierarchy from C++. But it turned out not to have anything to do with this - it was just a stack overflow (and not caused by an infinite loop as is usually the case, but caused by the fact that the stack was simply too small - seems like running QML in debug mode needs a lot of stack space).