variant 是 QML 通用属性类型。这种类型已经过时弃用,它的存在只是为了支持旧版应用。新的应用应该使用 var 替代。
一个 variant 类型可以代表任意 QML 基础类型:
Item {
property variant aNumber: 100
property variant aString: "Hello world!"
property variant aBool: false
}
当集成 C++ 时,注意,从 C++ 透传到 QML 的任何 QVariant 参数都会自动转换成 variant 类型,反之亦然。
用 variant 类型的稀有资源
variant 类型还可以表示图片或者像素集合。包含 QPixmap 或者 QImage 的 variant 类型变量就是 “稀有资源”,并且声明式引擎会在检测完任何需要复制的 JavaScript 表达式之后,试图自动释放这些资源。
客户端可以通过 JavaScript 调用 variant 属性上的 "destroy" 方法,显示释放这种稀有资源。同理也可以通过 JavaScript 调用 variant 属性上的 “preserve” 方法显示保护稀有资源。
存储数组和对象
variant 属性也可以表示:
- 一个基本类型值的数组
- 一个基本类型值的键值对map
例如,下面是一个 items 的数组 和 一个 attributes 的 map。用 for 循环检查它们内部,单个数组值可以通过下标访问,单个map值可以通过key访问。
Item {
property variant items: [1, 2, 3, "four", "five"]
property variant attributes: { 'color': 'red', 'width': 100 }
Component.onCompleted: {
for (var i = 0; i < items.length; i++)
console.log(items[i])
for (var prop in attributes)
console.log(prop, "=", attributes[prop])
}
}
诚然,这是一个存储数组和 map 的方便方式,但是你也一定注意到上面的 items 和 attributes 属性都不是 QML 对象(明显也不是JavaScript 对象)。键值对也不是 QML 属性。与此相反,只是 items 代表一个数组, attributes代表一个键值对 map。
此外,因为 items 和 attributes 不是 QML 对象,所以改编它们所包含的值不会触发属性更改提醒。如果上面的例子有 onItemsChanged 或者 onAttributesChanged 信号处理函数,那么在为它们的单个项分配值时,不会触发处理函数。但是,如果将 items 和 attributes 重新分配给不同的值,那么会触发处理程序。
JavaScript 程序员应该也注意到当一个 JS 对象被复制到一个数组或map属性时,复制的是对象内容(键值对),而不是对象本身。该属性不包含对原始对象的引用,对象的JavaScript原型链也在这个过程中被丢失。
这个基本类型由 QML 语言提供。