A variant type is a generic property type.
A variant is a generic property type. A variant type property can hold any of the 基本类型 值:
Item { property variant aNumber: 100 property variant aString: "Hello world!" property variant aBool: false }
The
variant
type can also hold:
For example, below is an
项
array and an
属性
map. Their contents can be examined using JavaScript
for
loops. Individual array values are accessible by index, and individual map values are accessible by 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]) } }
While this is a convenient way to store array and map-type values, you must be aware that the
项
and
属性
properties above are
not
QML objects (and certainly not JavaScript object either) and the key-value pairs in
属性
are
not
QML properties. Rather, the
项
property holds an array of values, and
属性
holds a set of key-value pairs. Since they are stored as a set of values, instead of as an object, their contents
cannot
be modified individually:
Item { property variant items: [1, 2, 3, "four", "five"] property variant attributes: { 'color': 'red', 'width': 100 } Component.onCompleted: { items[0] = 10 console.log(items[0]) // This will still be '1'! attributes.color = 'blue' console.log(attributes.color) // This will still be 'red'! } }
Additionally, since
项
and
属性
are not QML objects, changing their individual values do not trigger property change notifications. If the above example had
onNumberChanged
or
onAnimalChanged
signal handlers, they would not have been called. If, however, the
项
or
属性
properties themselves were reassigned to different values, then such handlers would be called.
One way to "update" the contents of an array or map is to copy the property to a JavaScript object, modify the copy as desired, and then reassign the property to the updated copy. Note, however, that this is not efficient. In the example below, which reassigns the
属性
特性,
entire
set of key-value pairs must be serialized and deserialized every time it is copied between a JavaScript object and a QML property:
Item { property variant attributes: { 'color': 'red', 'width': 100 } Component.onCompleted: { // Change the value of attributes.color to 'blue': var temp = attributes // copy all values to 'temp' temp.color = 'blue' attributes = temp // copy all values back to 'attributes' } }
Since this operation is inefficient, if a list or map should be modifiable, it is better to use alternative approaches. For example, you could implement a custom C++ list element, or write to a JavaScript object defined from within a JavaScript file.
JavaScript programmers should also note that when a JavaScript object is copied to an array or map property, the contents of the object (that is, its key-value properties) are copied, rather than the object itself. The property does not hold a reference to the original JavaScript object, and extra data such as the object's JavaScript prototype chain is also lost in the process.
另请参阅 QML 基本类型 .