[Development] [Interest] [Qt3D] Mixing C++ and QML

Shawn Rutledge Shawn.Rutledge at qt.io
Thu Oct 19 20:44:14 CEST 2017

(thread started on the interest list, but I don’t think my comments belong there)

On Oct 19, 2017, at 18:06, Sean Harmer <sean.harmer at kdab.com> wrote:

> Hi,
> you've hit one of the issues we did with exposing C++ and QML APIs. Namely, QQmlListProperty. This thing should ideally never have existed and instead support for properties of collections should have been added to QObject and the metaobject system.

What exactly do you think should be done there, in case we can fix it some day?

QObjects are normally managed as a tree for memory management purposes, so I’ve also long disliked the fact that it doesn’t quite match the nesting of the Item declarations in QML, because of the separate QList<QQuickItem *> childItems.  It’s confusing and wastes memory.

QQmlListProperty is flexible about storage, since you get to write all the accessors, so you can maybe use it just for QML and also have normal C++ API?

A typical pattern in QtQuick is that a QQmlListProperty is the default property, so declared children are automatically added.  But instead you have to declare the Components first, and then also add them to a vector.  Why is that?  It seems needlessly cumbersome to me.  If Components are naturally always children of Entities, then it ought to be enough to declare them inside an Entity.  But it seems that any QNode can have any number of QNode children, so maybe you could have a QQmlListPropery<QNode> as the default property, whose implementation uses the QObject children, just for convenience in QML? 

If you think there’s something wrong with the normal QObject parent/child relationship, then there’s another mechanism for detecting declared QML “children" and doing “something special” with them.  We use it to make each Window transient for whatever Window or Item’s window that it was declared inside of, for adding PointerHandlers to Items, and stuff like that: any case where one object can be declared inside another, but it’s not quite a conventional parent/child relationship, for example because the “parent” and “child” aren’t the same kind of objects.

Either of those mechanisms can keep the syntax nice in QML.

> To avoid pulling in a QtQml dependency in the C++ API, we instead have another layer to add the QML specifics (pretty much entirely list properties).

Ugh that would indeed be nice to simplify.

> In order to create these from code we have a factory. Try something like:
> QAbstractNodeFactory::createNode<QEntity>("QEntity")
> If using just C++ you will get a standard QEntity. If using QML (and the types are registered with the factory) you will get the QML -enhanced version with the extension object that handles the list properties.

If we had collection properties in QObject somehow, would you get rid of the factories?   Or everything is stuck in place now because of having public API?

More information about the Development mailing list