This examples gives me property binding errors:
file:///home/user/qmltests/layouts.qml:22:4: QML Label: Binding loop detected for property "font.pixelSize"
file:///home/user/qmltests/layouts.qml:22:4: QML Label: Binding loop detected for property "font.pixelSize"
file:///home/user/qmltests/layouts.qml:18:4: QML Label: Binding loop detected for property "font.pixelSize"
Code:
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.11
Page {
id: root
width: 400
height: 200
StackLayout {
id: main_container
Layout.fillWidth:true
Layout.fillHeight:true
ColumnLayout {
id: sub_container
Layout.fillWidth:true
Layout.fillHeight:true
Label {
text: "One"
font.pixelSize: sub_container.height*0.2
}
Label {
text: "Two"
font.pixelSize: sub_container.height*0.2
}
}
}
}
By logic, this shouldn't happen, because I am copying the width
and height
down to lower level components by using Layout.fillWidth=true
and layout.fillHeight=true
To fix this error, I have to copy the heigth from the root element:
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.11
Page {
id: root
width: 400
height: 200
StackLayout {
id: main_container
Layout.fillWidth:true
Layout.fillHeight:true
ColumnLayout {
id: sub_container
Layout.fillWidth:true
Layout.fillHeight:true
Label {
text: "One"
font.pixelSize: root.height*0.2
}
Label {
text: "Two"
font.pixelSize: root.height*0.2
}
}
}
}
Why aren't width
and height
propagated from the root
elements down to children layouts?
How can I reference sub_container.width
and sub_container.height
(because it is known before items are laid out) without getting binding loop error? I don't want to reference the root item because due to complexity there may be many layouts inside root item and in order to lay out components in a scalable way I need to know the width and height of the parent layout.
If you use layouts, the elements they manage must not change their size based on size given by the layout. To do what you wish to do, you shouldn’t be using a layout, but anchors, since you want to manage the child sizes manually. The loop is there because the layout uses the size of your item to resize itself, that your item then uses to resize itself, endlessly. If you don’t need that functionality, it will interfere – as you have seen. The reason it worked via root is that root’s size is not managed by the layout: it’s fixed. And that’s what you wanted all along, isn’t it?
Another approach would be for the label not to change its size hint based on font size, so that the layout wouldn’t react to the font size change.
TL;DR: Layouts size themselves based on child sizes, thus there’s a loop if the child sizes itself based on the layout’s size.