[Development] [Interest] [Qt3D] Mixing C++ and QML
Sean Harmer
sean.harmer at kdab.com
Fri Oct 20 12:33:27 CEST 2017
Hi,
On 19/10/2017 19:44, Shawn Rutledge wrote:
> (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?
Probably something like how NSObject manages properties of collections.
So far with Qt3D we've only needed the same level of semantics as
offered by QQmlListProperty - or rather we've worked within those
constraints. So a simple indexed container with the ability to
add/remove items.
In a more general setting I can easily also imagine support for
associative containers too.
The tricky part will be deciding which semantics do we wish to support
and where do we draw the line between such properties and recommending
to use a full-blown model instead.
Speaking of which, improving QAIM to be able to return data for
contiguous blocks of indices in one function call would be a really
welcome addition. Calling so many virtuals to retrieve a single data
value for a single index and role is not exactly efficient. The existing
QAIM API is fine for the existing views but doesn't scale well when
trying to use them to populate, say a buffer of per instance data on a
large scale. Yes I know we could avoid this with custom API but users
have so many models at this point it would be nice to offer some
interoperability with them.
>
> 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.
We avoided that in Qt 3D and just use the regular parent-child
relationship. We don't have separation between visual parent and QObject
parent.
> 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?
That's what we did. The C++ API has addComponent(), removeComponent(),
componentCount() type functions, and then we have libraries sat on top
for each aspect that add in the QQmlListProperty handling via extension
objects. For e.g.
http://code.qt.io/cgit/qt/qt3d.git/tree/src/quick3d/quick3drender
> 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,
^ that is your broken assumption. Components do not have to be children
of the entity. We actually started out with that but found that it
prohibits sharing components which can sometimes be handy.
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?
Also whilst I'm here, there's an annoying limitation in the QML language
that prevents mixing inline declaration of elements with elements
referenced by id in a list property. That is you cannot write something
like:
Mesh { id: mesh }
Material { id: material }
Entity {
components: [ Transform {}, material, mesh ]
}
> 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.
Do you mean the autoparent callback?
http://code.qt.io/cgit/qt/qt3d.git/tree/src/quick3d/quick3d/qt3dquick_global.cpp#n676
We need this here because it's not enough for us to know that the parent
is a QObject. We need to know if it's a QNode to be able to add the new
child to the scene.
One possible future solution we discussed with Lars and Simon for this
is to make QObjectPrivate::setParent() virtual.
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?
I don't know if we could get rid of the factories yet, I've not thought
it through sufficiently yet. However, if QObject properties could handle
collections, we could certainly get rid of all the extension object
boiler plate in the quick3dFoo libraries:
http://code.qt.io/cgit/qt/qt3d.git/tree/src/quick3d
which in itself would be a very nice saving.
Cheers,
Sean
--
Dr Sean Harmer | sean.harmer at kdab.com | Managing Director UK
KDAB (UK) Ltd, a KDAB Group company
Tel. +44 (0)1625 809908; Sweden (HQ) +46-563-540090
Mobile: +44 (0)7545 140604
KDAB - Qt Experts
More information about the Development
mailing list