I'm creating a custom QML component (a specialization of ListView
that allows multiple selection). I'd like to provide attached properties to objects provided to my component. I see how to create attached properties using C++. However, I cannot find information on adding custom properties in pure QML. Is this possible using QML?

- 296,393
- 112
- 651
- 745
-
Someone has to find a quote from a doc. AFAIK there is no QML syntax for that. – Velkan Sep 02 '16 at 10:57
-
1I think it's only possible from C++. – David K. Hess Sep 02 '16 at 11:20
2 Answers
Is this possible using QML?
No.

- 23,716
- 9
- 83
- 122
-
-
3Oh, and it might be nice to mention this in documentation somewhere in [this section](http://doc.qt.io/qt-5/qtqml-syntax-objectattributes.html#attached-properties-and-attached-signal-handlers). – Phrogz Sep 02 '16 at 12:42
There is an alternative, easy and clean way to this in QML - just use an adapter object that implements the desired properties. Then instead of attaching just nest into the adapter - use it as as a parent / container. You can also nest objects into the adapter, getting another C++ exclusive - grouped properties. A possible way to minimize the overhead of this is to use JS objects and properties, with a downside - no change notifications, which you can somewhat mitigate by emitting manually.
An example:
// Adapter.qml - interface with attached properties
Item {
id: adapter
property int customInt : Math.random() * 1000
property var group : {"a" : Math.random(), "b" : Math.random() }
default property Component delegate
width: childrenRect.width
height: childrenRect.height
Component.onCompleted: delegate.createObject(adapter)
}
// usage
ListView {
width: 100
height: 300
model: 5
delegate: Adapter {
Row {
spacing: 10
Text { text: index }
Text { text: customInt }
Text { text: group.a }
Text { text: group.a }
}
}
}
It is fairly painless and convenient compared to some other QML workarounds. You don't even have to do parent.parent.customInt
- the properties are directly accessible as if they are attached, this works because of dynamic scoping. The default property
allows to avoid setting the inner delegate as a property you just nest the delegate you want directly in the adapter.
In many cases those acrobatics are overkill, you can just wrap in place:
ListView {
width: 100
height: 300
model: 5
delegate: Item {
width: childrenRect.width
height: childrenRect.height
property string custom1: "another"
property string custom2: "set of"
property string custom3: "properties"
Row {
spacing: 10
Text { text: index }
Text { text: custom1 }
Text { text: custom2 }
Text { text: custom3 }
}
}
}
The only key part really is the binding for the size of the adapter object so that the view can properly layout the objects. I routinely use a Wrap
element which essentially does the same but is implemented in C++, which is much more efficient than a QML binding.

- 47,916
- 17
- 112
- 190
-
Can you provide an example illustrating what you suggest? I'm having trouble picturing it. – Phrogz Sep 30 '16 at 17:05
-