考虑这个项目结构:
MyComponent.qml:
Item {
id: innerId
}
Usage.qml:
MyComponent {
id: outerId
}
乍一看,似乎这会创建一个同时具有2个不同id的单个对象。但如果将id
视为财产,则这是不可能的。
对我而言,id
似乎不是对象的属性,因为它是对象声明的属性。这是真的吗?
它将解释我如何在innerId
中将对象称为MyComponent.qml
,在outerId
中将Usage.qml
称为stringa,stringb
stringb,stringc
stringd,stringa
,但它在两个地方都是相同的对象。< / p>
答案 0 :(得分:3)
id
仅在该qml文件中可见。 id是不是属性,而是一个特殊属性。不要让语法欺骗你,它只是为了与qml的习语一致,它可能看起来像一个属性,但它完全不同。
id属性
每个QML对象类型都只有一个id属性。这个属性是 由语言本身提供,不能重新定义或覆盖 任何QML对象类型。
可以将值分配给对象实例的id属性 允许该对象被其他对象识别和引用。 此ID必须以小写字母或下划线开头,并且 不能包含字母,数字和下划线以外的字符。
从技术上讲,它可能看起来两个ID都引用同一个对象,但事实并非如此,innerId
引用Item
中的MyComponent.qml
实例和outerId
引用MyComponetn
中的Usage.qml
个实例。实际上,如果您console.log(id)
和MyComponetn
Usage
,您将获得相同的对象实例,因为MyComponent {}
实例只是该Item
实例的另一个名称MyComponent.qml
。
id不是属性,只能从该文件内部访问,如果需要从外部公开某些对象,则需要执行此操作:
Item { // Something.qml
property Item innerItem : innerId
Item {
id: innerId
}
}
对我来说,似乎id不是对象的属性 是对象声明的属性。这是真的吗?
id用于引用当前qml文件中某个qml类型的实例。如果通过“对象声明”表示实例,那么是的,这是真的。 IMO“对象”是一个含糊不清的东西,因为一个对象可以是很多东西,一个对象可以是一个类型,一个实例,一个属性,一个函数,一个JS对象......在这方面我认为“每个QML对象类型只有一个id属性“从文档中没有正确的措辞。
id仅适用于qml类型实例,属性和函数以不同的方式工作,可从外部访问。
如果你需要对它的用途进行类比,可以将id看作类似于私有类成员的东西 - 它只在类型中可见,如果你需要将它暴露给外面 - 你需要为它制作一个存取器。
这似乎创建了一个具有2个不同id的单个对象 同时
事实并非如此,因为您无法使用MyComponent
解决innerId
,所以不,它没有2个不同的ID,它没有任何 ids。 id实际上并不属于该对象,它只是在当前源文件中与它关联。如上所述,两个id将引用同一个对象,但该对象没有两个id。
它的工作原理(我并不是指实际的实现)类似于C ++中的引用。您可以在不同的位置以不同的名称对同一对象进行多次引用。在qml中,您不必为C ++中的实例编写名称,但是如果要引用对象,通常的方法是使用id,尽管取决于对象树,您也可以使用父属性。不建议在大qml文件中过度使用ID,因为这可能会降低性能。
另外,请注意,与ids不同,您可以非常“覆盖”函数和属性,并且行为在this question中有详细说明,例如,如果使用字符串属性覆盖int属性,该对象将最终具有该属性两次,但如果迭代该对象,则不会找到一个int和一个字符串,而是字符串两次。