[Interest] QQmlPropertyList x QList in hybrid C++/QML APIs

Alan Alpert 416365416c at gmail.com
Fri Jun 14 20:59:09 CEST 2013


On Fri, Jun 14, 2013 at 11:49 AM, Sandro Andrade <sandroandrade at kde.org> wrote:
> On Fri, Jun 14, 2013 at 2:48 PM, Alan Alpert <416365416c at gmail.com> wrote:
>> To use types across QML/C++ you should use qmlRegisterType.
>> QObject-based types aren't automatically registered with QML, but
>> certain things may still work. element.ownedAttributes is undefined
>> because you haven't registered the type.
>>
>
> Ok, I've confirm that, but it seems that properties with type QList<T *>
> still are handled as QVariant(QList<T *>), even if T is registered in QML.
> It works only if property type is QVariantList, is that right ?

If you register both T and the class the property is on to QML, then
you should be able to use QList<T*> property as a read-only list of T.
QQmlListProperty is only strictly necessary when the list can be
modified from QML.

> Changing all my properties to QVariantList would imply a somehow weaker
> type safety in my API :(

Yeah, you shouldn't need to do that.

>> However you don't have to maintain two different classes. You can just
>> register the same C++ class into QML. To interact with the list
>> property properly (mostly just assigning to it in QML, i.e. UmlClass {
>> ownedOperations: [UmlOperation {}] } ) you need to have a
>> QQmlListProperty type property, not just the QList<QObject*> property.
>> But the QQmlListProperty type is basically just a wrapper around a
>> QList<QObject*> (providing better control of the allocation if you
>> need it), so it will be using the same QList<QObject*> as the data.
>> You just need the extra property, not duplicating or synchronizing
>> data, so it's easy to put it on the same C++ class and there's very
>> little more you have do to use it properly in QML.
>
> Ok, but that requires a new property name to prevent name clashing,
> doesn't it ? I'd have to have something like:
>
> Q_PROPERTY(QList<QUmlProperty *> ownedAttributes READ ownedAttributes)
> and
> Q_PROPERTY(QQmlListProperty<QUmlProperty *> qmlOwnedAttributes READ
> ownedAttributes)

Yes. But this usually isn't a problem for one of the following reasons

A) You only access the property as a property from QML, so the
QQmlListProperty is the only property needed (the ownedAttributes
method still returns the QList for the C++ API, and the
qmlOwnedAttributes method for the QQmlListProperty isn't used from
C++).
B) You almost always access the property from QML as a default
property, like the children property in QQuickItem. Then the second
name doesn't matter because it's never explicitly typed.

Option A) is recommended for a cleaner QML API anyways. If you want a
clean QML API and use the properties heavily from C++, then you do run
into this problem where the best workaround is a separate QML
(sub)class.

--
Alan Alpert



More information about the Interest mailing list