Custom attached properties in QML

巧了我就是萌 提交于 2019-12-12 17:54:28

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!