问题
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?
回答1:
Is this possible using QML?
No.
回答2:
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.
来源:https://stackoverflow.com/questions/39285077/custom-attached-properties-in-qml