Consider this project structure:
MyComponent.qml:
Item {
id: innerId
}
Usage.qml:
MyComponent {
id: outerId
}
At first glance it seems like this creates a single object that has 2 different id's simultaneously. But that's impossible, if id
is to be considered a property.
To me it seems that an id
is not so much a property of an object as it is a property of an object declaration. Is that true?
It would explain how I can refer to the object as innerId
in MyComponent.qml
and as outerId
in Usage.qml
yet have it be the same object in both places.
The
id
is only visible inside that qml file. The id is not a property, but a special attribute. Don't let the syntax fool you, it was just intended to be in line with qml's idioms, it may look like a property but it is something different altogether.Technically, it may appear both ids reference the same object, but that's not the case, the
innerId
references theItem
instance inMyComponent.qml
, and theouterId
references theMyComponetn
instance inUsage.qml
. In practice, if youconsole.log(id)
fromMyComponetn
andUsage
you will get the same object instance, since theMyComponent {}
instance is just another name for thatItem
fromMyComponent.qml
.The id is not a property, and it can only be access from inside that file, if you need to expose some object to be visible from the outside, you need to do this:
The id is used to refer to an instance of some qml type in the current qml file. If by "object declaration" you mean an instance, then yes, it is true. IMO "object" is a ambiguous, as an object can be a lot of things, an object can be a type, an instance, a property, a function, a JS object... In this regard I think the "Every QML object type has exactly one id attribute" from the documentation is not worded properly.
The id only applies to qml type instances, properties and functions work in a different way, and are accessible from the outside.
If you need to make an analogy to what it's used for, an id might be seen as something similar to a private class member - it is only visible inside the type, and if you need to expose it to the outside - you need to make an accessor for it.
This is not true, as you won't be able to address
MyComponent
withinnerId
, so no, it doesn't have 2 different ids, it doesn't have any ids. The id does not really belong to the object, it is just associated to it in the current source file. As mentioned above, the two ids will be referring to the same object, but the object doesn't have two ids.An analogy to how it works (and I don't mean the actual implementation) would be something similar to references in C++. You can have multiple references to the same object, in different places and with different names. In qml you don't have to write names for instances like in C++, but if you want to refer to an object the usual approach is to use an id, although depending on the object tree you can use the parent property as well. It is not recommended to go overboard with ids in big qml files, as that could degrade performance.
Also, note that unlike ids, you can very much "override" functions and properties, and the behavior is kind of iffy as elaborated in this question, for example, if you override an int property with a string property, the object will end up having that property twice, but if you iterate the object, you will not find one int and one string, but the string twice.