What is the difference between width
/height
and implicitWidth
/Height
in QML?
When should one set the implicit dimensions instead of the regular? When should one ask the implicit dimensions instead of the regular from a component/item?
Generally, usage of implicitHeight/Width
only makes sense within reusable components.
It gives a hint, of the natural size of the Item without enforcing this size.
Let's take a Image
as an example. The natural size of the image would map one pixel from the image file to one pixel on the screen. But it allows us to stretch it, so the size is not enforced and can be overridden.
Let's say now, we want to have a gallery with pictures of unknown dimension, and we don't want to grow but only shrink them if necessary. So we need to store the natural size of the image. That is, where the implicit height comes into play.
Image {
width: Math.max(150, implicitWidth)
height: Math.max(150, implicitHeight)
}
In custom components, you have a choice on how to define the sizes.
The one choice is, to have all dimensions relative to the components root
-node, maybe like this:
Item {
id: root
Rectangle {
width: root.width * 0.2
height: root.height * 0.2
color: 'red'
}
Rectangle {
x: 0.2 * root.width
y: 0.2 * root.height
width: root.width * 0.8
height: root.height * 0.8
color: 'green'
}
}
In this case, there is no natural size of the object. Everything works out perfectly for each size you set for the component.
On the other hand, you might have an object, that has a natural size - that happens, e.g. if you have absolute values in it
Item {
id: root
property alias model: repeater.model
Repeater {
id: repeater
delegate: Rectangle {
width: 100
height: 100
x: 102 * index
y: 102 * index
}
}
}
In this example you should provide the user with information about the natural size, where the content does not protude the item. The user might still decide to set a smaller size and deal with the protrusion, e.g. by clipping it, but he needs the information about the natural size to make his decision.
In many cases, childrenRect.height/width
is a good measure for the implcitHeight/Width
, but there are examples, where this is not a good idea. - e.g. when the content of the item has x: -500
.
A real life example is the Flickable
that is specifically designed to contain larger objects than its own size. Having the size of the Flickable
to be equal to the content would not be natural.
Also be careful, when using scale
in custom components, as the childrenRect will not know about the scaling.
Item {
id: root
implicitWidth: child.width * child.scale
implicitHeight: child.height * child.scale
Rectangle {
id: child
width: 100
height: 100
scale: 3
color: 'red'
}
}
And to your comment: I just don't understand why it is better to set implicitWidth/Height instead of setting width/height of a component's root dimension.
implicitWidht/Height
are not a necessety - QtQuick could do without them. They exist for convenience and shall be convention.
Rule of Thumb
When you want to set dimension of a root node of a reusable component, set
implicitWidth/Height
.
In some cases, set it for non-root-nodes, if the nodes are exposed as a property.
Do so only, if you have a reason for it (many official components come without any).
When you use a component, setwidth/height
.