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++ 存储类型导致的。

  1. 从序列中删除元素将导致使用默认构造的值替换该元素,而不是 undefined 值。
  2. 将序列的 length 属性设置为大于其当前值的数值,会导致序列被填充到指定的长度,填充的元素是默认构造的,而不是 undefined 元素。
  3. Qt 容器类支持有符号整数索引(而不是无符号整数值);因此,尝试访问大于 qsizetype 能够持有的最大数的索引将失败。

如果您想从序列中删除元素而不是简单地用默认构造的值替换它们,不要使用索引删除操作符(delete sequence[i]),而应使用 splice 函数(sequence.splice(startIndex, deleteCount))。

通常,任何由 QMetaSequence 识别的容器都可以通过 Q_PROPERTYQ_INVOKABLE 方法从 C++ 传递给 QML。这包括但不限于,所有注册的 QListQQueueQStackQSet、std::list、std::vector,这些容器包含使用 Q_DECLARE_METATYPE 标记的类型。

通过 QMetaSequence 使用序列会导致昂贵的数据处理。为了避免这些转换,您可以通过从 C++ 使用 QML_SEQUENTIAL_CONTAINER 注册自定义的匿名序列类型。用这种方式注册的类型的行为与预定义的序列类型相同,并且按原样存储。然而,它们没有 QML 名称。

警告: 存储为类似于 QListstd::vector 的 C++ 容器的序列受 QML 值类型和序列引用 的影响,因此应谨慎处理。由于 QQmlListProperty 只是对底层容器的视图,所以它不受影响。C++ 标准容器,如 std::vector,不是隐式共享的。因此,复制它们始终会产生深拷贝。由于从属性读取的序列始终至少需要复制一次,因此即使在 QML 中不对其进行修改,使用此类容器作为 QML 序列也是相当昂贵的。

QtQml 模块包含了一些您可能希望使用的序列类型

© 2024 The Qt Company Ltd. 本文档中包含的文档贡献归各自所有者所有。提供的文档根据自由软件基金会发布的GNU自由文档许可版本1.3的条款授权。Qt及其相关商标是芬兰和/或其他国家的The Qt Company Ltd的商标。所有其他商标均为各自所有者的财产。