Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-118511

Binding loop if ColumnLayout implicitWidth is changed

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P3: Somewhat important
    • 6.5.7, 6.7.1, 6.8.0 FF
    • 6.5.3, 6.6.0
    • Quick: Layouts
    • 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.

       

       

      Attachments

        For Gerrit Dashboard: QTBUG-118511
        # Subject Branch Project Status CR V

        Activity

          People

            santhoshkumar Santhosh Kumar Selvaraj
            c.geist Christoph Geist
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: