QML 中的自定义附加属性

Custom attached properties in QML

我正在创建自定义 QML 组件(ListView 的特化,允许多项选择)。我想为提供给我的组件的对象提供附加属性。我看看如何create attached properties using C++。但是,我找不到有关在纯 QML 中添加自定义属性的信息。这可能使用 QML 吗?

Is this possible using QML?

没有

在 QML 中有一种替代、简单和干净的方法 - 只需使用实现所需属性的适配器对象。然后,与其将嵌套附加到适配器中,不如将其用作父/容器。您还可以将对象嵌套到适配器中,获得另一个 C++ 独有的分组属性。最小化这种开销的一种可能方法是使用 JS 对象和属性,但有一个缺点 - 没有更改通知,您可以通过手动发出来减轻这种情况。

一个例子:

// 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 }
    }
  }
}

与其他一些 QML 解决方法相比,它相当轻松和方便。您甚至不必执行 parent.parent.customInt - 属性可以直接访问,就好像它们是附加的一样,这是因为动态作用域。 default property 允许避免将内部委托设置为 属性 你只需将你想要的委托直接嵌套在适配器中。

在很多情况下,那些杂技动作有点矫枉过正,你可以原地包裹起来:

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 }
    }
  }
}

真正关键的部分是绑定适配器对象的大小,以便视图可以正确布局对象。我经常使用 Wrap 元素,它本质上做同样的事情,但用 C++ 实现,这比 QML 绑定更有效。