QML 序列类型
对于每种 对象类型 和 值类型,QML 会自动生成一个序列类型来存储该类型的多个实例。您可以使用 list
关键字创建序列类型的属性。
import QtQml QtObject { property list<int> ints: [1, 2, 3, 4] property list<Connection> connections: [ Connection { // ... }, Connection { // ... } ] }
值类型的序列实现为 QList,而对象类型的序列实现为 QQmlListProperty。
QML 中的序列通常表现得像 JavaScript 的 Array
类型,但也有一些重要的区别,这是由于实现中使用了 C++ 存储类型导致的。
- 从序列中删除元素将导致使用默认构造的值替换该元素,而不是
undefined
值。 - 将序列的
length
属性设置为大于其当前值的数值,会导致序列被填充到指定的长度,填充的元素是默认构造的,而不是undefined
元素。 - Qt 容器类支持有符号整数索引(而不是无符号整数值);因此,尝试访问大于 qsizetype 能够持有的最大数的索引将失败。
如果您想从序列中删除元素而不是简单地用默认构造的值替换它们,不要使用索引删除操作符(delete sequence[i]
),而应使用 splice
函数(sequence.splice(startIndex, deleteCount)
)。
通常,任何由 QMetaSequence 识别的容器都可以通过 Q_PROPERTY 或 Q_INVOKABLE 方法从 C++ 传递给 QML。这包括但不限于,所有注册的 QList、QQueue、QStack、QSet、std::list、std::vector,这些容器包含使用 Q_DECLARE_METATYPE 标记的类型。
通过 QMetaSequence 使用序列会导致昂贵的数据处理。为了避免这些转换,您可以通过从 C++ 使用 QML_SEQUENTIAL_CONTAINER 注册自定义的匿名序列类型。用这种方式注册的类型的行为与预定义的序列类型相同,并且按原样存储。然而,它们没有 QML 名称。
警告: 存储为类似于 QList 或 std::vector
的 C++ 容器的序列受 QML 值类型和序列引用 的影响,因此应谨慎处理。由于 QQmlListProperty 只是对底层容器的视图,所以它不受影响。C++ 标准容器,如 std::vector
,不是隐式共享的。因此,复制它们始终会产生深拷贝。由于从属性读取的序列始终至少需要复制一次,因此即使在 QML 中不对其进行修改,使用此类容器作为 QML 序列也是相当昂贵的。
QtQml 模块包含了一些您可能希望使用的序列类型。
© 2024 The Qt Company Ltd. 本文档中包含的文档贡献归各自所有者所有。提供的文档根据自由软件基金会发布的GNU自由文档许可版本1.3的条款授权。Qt及其相关商标是芬兰和/或其他国家的The Qt Company Ltd的商标。所有其他商标均为各自所有者的财产。