Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between width, height and implicitWidth/Height and corresponding use-cases in QML

Tags:

qt

qml

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?

like image 398
Silex Avatar asked Aug 29 '17 19:08

Silex


People also ask

What is implicitWidth in QML?

implicitWidth : realDefines the natural width or height of the Item if no width or height is specified. The default implicit size for most items is 0x0, however some items have an inherent implicit size which cannot be overridden, for example, Image and Text .

What is item in QML?

The Item type is the base type for all visual items in Qt Quick. All visual items in Qt Quick inherit from Item. Although an Item object has no visual appearance, it defines all the attributes that are common across visual items, such as x and y position, width and height, anchoring and key handling support.


2 Answers

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, set width/height.

like image 160
derM Avatar answered Oct 07 '22 14:10

derM


I don't have the definitive answer but I can tell you what I found out. First, from the documentation:

implicitWidth : real

Defines the natural width or height of the Item if no width or height is specified.

The default implicit size for most items is 0x0, however some items have an inherent implicit size which cannot be overridden, for example, Image and Text.

but less informative for width:

width

Defines the item's position and size.

The width and height reflect the actual size of the item in the scene. The implicit size is some kind of inherent property of the item itself.1

I use them as follows: When I create a new item and it can be resized, I set an implicit size inside the object2. When I'm using the object, I often set the real size explicitly from the outside.

The implicit size of an object can be overridden by setting height and width.

an example: TextWithBackground.qml

Item {     implicitWidth: text.implicitWidth     implicitHeight: text.implicitHeight     // the rectangle will expand to the real size of the item     Rectangle { anchors.fill: parent; color: "yellow" }     Text { id: text; text: "Lorem ipsum dolor..." } } 

an example: MyWindow.qml

Item {     width: 400     height: 300     TextWithBackground {          // half of the scene, but never smaller than its implicitWidth          width: Math.max(parent.width / 2, implicitWidth)          // the height of the element is equal to implicitHeight          // because height is not explicitly set     } } 

1) For some elements, like Text, the implicit height depends on the (not-implicit) width.
2) The implicit size usually depends on the implicit size of its children.

like image 28
Georg Schölly Avatar answered Oct 07 '22 13:10

Georg Schölly