Details
-
Bug
-
Resolution: Fixed
-
P3: Somewhat important
-
6.5.3, 6.6.0
-
None
-
9ad9d05f2 (dev), a1d551428 (6.7), 1570bd5f8 (6.6), e3022f58f (tqtc/lts-6.5), 3fa471978 (dev), 0790b899c (6.7), 289e8f902 (tqtc/lts-6.5)
Description
The following code produces a binding loop on ColumnLayout.implicitWidth which we don't understand, once the button is clicked.
import QtQuick import QtQuick.Layouts import QtQuick.Window import QtQuick.Controls.Material Window { width: 1000 height: 1000 visible: true Item { id: root anchors.fill: parent property var customWidth: 100 ColumnLayout { id: col Item { id: item implicitHeight: 80 implicitWidth: { let val = Math.max(col2.implicitWidth, root.customWidth + 20); print("item", val); return val; } onImplicitWidthChanged: { print("item (implicit changed)", item.implicitWidth); } ColumnLayout { id: col2 width: { let val = parent.width; print("col2 (width)", val); return val; } onWidthChanged: { print("col2 (width changed)", col2.width); } onImplicitWidthChanged: { print("col2 (implicit changed)", col2.implicitWidth); } Rectangle { id: rect implicitWidth: { print("rect", root.customWidth); return root.customWidth; } onImplicitWidthChanged: { print("rect (changed)", rect.implicitWidth); } implicitHeight: 80 color: "green" } } } Button { id: emit text: "emit" onClicked: { print("! emit begin"); root.customWidth += 1 print("! emit end"); } } } } }
This produces the following output:
qml: rect 100 qml: rect (changed) 100 qml: item 120 qml: item (implicit changed) 120 qml: col2 (width) 120 qml: col2 (width changed) 120 qml: col2 (implicit changed) 100 qml: item 120 qml: ! emit begin <--- button is clicked here! qml: rect 101 qml: rect (changed) 101 qml: item 121 qml: col2 (width) 121 qml: col2 (width changed) 121 qml: col2 (implicit changed) 101 qrc:/main.qml:20:13: QML QQuickItem: Binding loop detected for property "implicitWidth" qml: item (implicit changed) 121 qml: ! emit end
The order is surprisingly different if the ColumnLayout is replaced with a Colunm. Then the col.implicitWidth only gets evaluated AFTER the button event ("emit" print) has been completed and no binding loops occurs! The output looks like this:
qml: rect 100 qml: rect (changed) 100 qml: item 120 qml: item (implicit changed) 120 qml: col2 (width) 120 qml: col2 (width changed) 120 qml: col2 (implicit changed) 100 qml: item 120 qml: ! emit begin qml: rect 101 qml: rect (changed) 101 qml: item 121 qml: col2 (width) 121 qml: col2 (width changed) 121 qml: item (implicit changed) 121 qml: ! emit end qml: col2 (implicit changed) 101 qml: item 121
In this example we expect the ColumnLayout and Column to behave the same since we don't use any Layout-specific features, using both just as a simple positioners.