Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Strange ListView behaviour (depending on types of anchors)
Qt 6.12 LTS is out! See what's new in the release blog

Strange ListView behaviour (depending on types of anchors)

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
10 Posts 2 Posters 1.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    paulmasri
    wrote on last edited by paulmasri
    #1

    Why is it that the following two ListViews show up differently? The only difference in the QML is that one is positioned using anchors.fill: parent while the other is positioned using parent.left, .top, .width & .height.

    Both lists use positionViewAtBeginning() on completed and set the Delegate width to 1/8th ListView width.

    I suspect it has something to do with the Delegate width having a data binding to the ListView width, since a fixed width behaves 'properly', but the code looks valid to me in both cases.

    Case 1

    ListView { id: case1
      anchors.fill: parent
      orientation: Qt.Horizontal
      interactive: false
    
      model: 20
      delegate: Rectangle {
        width: case1.width / 8
        height: case1.height
        border.color: "lightblue"
        border.width: 1
    
        Text {
          anchors.fill: parent
          horizontalAlignment: Text.AlignHCenter
          verticalAlignment: Text.AlignVCenter
          text: model.index
        }
      }
    
      Component.onCompleted: positionViewAtBeginning()
    }
    

    Positioned at start of list as expected, with cell widths as expected.

    Screenshot 2022-09-14 at 11.41.58.png

    Case 2

    ListView { id: case2
      anchors.left: parent.left
      anchors.top: parent.top
      width: parent.width //EDIT: corrected typo here
      height: parent.height //EDIT: corrected typo here
      orientation: Qt.Horizontal
      interactive: false
    
      model: 20
      delegate: Rectangle {
        width: case2.width / 8
        height: case2.height
        border.color: "lightblue"
        border.width: 1
    
        Text {
          anchors.fill: parent
          horizontalAlignment: Text.AlignHCenter
          verticalAlignment: Text.AlignVCenter
          text: model.index
        }
      }
    
      Component.onCompleted: positionViewAtBeginning()
    }
    

    Neither the position within the list nor the cell widths are as expected.

    Screenshot 2022-09-14 at 11.42.46.png

    Delving deeper, I put a console.log() on the Component.onCompleted for both the ListView and the Delegate to output their widths.

    Case 1 widths

    qml: Delegate 0: -30
    qml: Delegate 1: -30
    qml: Delegate 2: -30
    qml: Delegate 3: -30
    qml: Delegate 4: -30
    qml: Delegate 5: -30
    qml: Delegate 6: -30
    qml: Delegate 7: -30
    qml: Delegate 8: -30
    qml: Delegate 9: -30
    qml: Delegate 10: -30
    qml: Delegate 11: -30
    qml: Delegate 12: -30
    qml: Delegate 13: -30
    qml: Delegate 14: -30
    qml: Delegate 15: -30
    qml: Delegate 16: -30
    qml: Delegate 17: -30
    qml: Delegate 18: -30
    qml: Delegate 19: -30
    qml: Delegate 10: 70
    qml: Delegate 11: 70
    qml: Delegate 12: 70
    qml: Delegate 13: 70
    qml: Delegate 14: 70
    qml: Delegate 15: 70
    qml: Delegate 16: 70
    qml: Delegate 17: 70
    qml: Delegate 18: 70
    qml: Delegate 1: 70
    qml: Delegate 2: 70
    qml: Delegate 3: 70
    qml: Delegate 4: 70
    qml: Delegate 5: 70
    qml: Delegate 6: 70
    qml: Delegate 7: 70
    qml: Delegate 8: 70
    qml: ListView: 560
    qml: Delegate 9: 70
    qml: Delegate 10: 70
    qml: Delegate 11: 70
    qml: Delegate 12: 70
    

    Case 2 widths

    qml: Delegate 0: -30
    qml: Delegate 1: -30
    qml: Delegate 2: -30
    qml: Delegate 3: -30
    qml: Delegate 4: -30
    qml: Delegate 5: -30
    qml: Delegate 6: -30
    qml: Delegate 7: -30
    qml: Delegate 8: -30
    qml: Delegate 9: -30
    qml: Delegate 10: -30
    qml: Delegate 11: -30
    qml: Delegate 12: -30
    qml: Delegate 13: -30
    qml: Delegate 14: -30
    qml: Delegate 15: -30
    qml: Delegate 16: -30
    qml: Delegate 17: -30
    qml: Delegate 18: -30
    qml: Delegate 19: -30
    qml: ListView: 560
    
    J.HilkJ 1 Reply Last reply
    0
    • P paulmasri

      Why is it that the following two ListViews show up differently? The only difference in the QML is that one is positioned using anchors.fill: parent while the other is positioned using parent.left, .top, .width & .height.

      Both lists use positionViewAtBeginning() on completed and set the Delegate width to 1/8th ListView width.

      I suspect it has something to do with the Delegate width having a data binding to the ListView width, since a fixed width behaves 'properly', but the code looks valid to me in both cases.

      Case 1

      ListView { id: case1
        anchors.fill: parent
        orientation: Qt.Horizontal
        interactive: false
      
        model: 20
        delegate: Rectangle {
          width: case1.width / 8
          height: case1.height
          border.color: "lightblue"
          border.width: 1
      
          Text {
            anchors.fill: parent
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
            text: model.index
          }
        }
      
        Component.onCompleted: positionViewAtBeginning()
      }
      

      Positioned at start of list as expected, with cell widths as expected.

      Screenshot 2022-09-14 at 11.41.58.png

      Case 2

      ListView { id: case2
        anchors.left: parent.left
        anchors.top: parent.top
        width: parent.width //EDIT: corrected typo here
        height: parent.height //EDIT: corrected typo here
        orientation: Qt.Horizontal
        interactive: false
      
        model: 20
        delegate: Rectangle {
          width: case2.width / 8
          height: case2.height
          border.color: "lightblue"
          border.width: 1
      
          Text {
            anchors.fill: parent
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
            text: model.index
          }
        }
      
        Component.onCompleted: positionViewAtBeginning()
      }
      

      Neither the position within the list nor the cell widths are as expected.

      Screenshot 2022-09-14 at 11.42.46.png

      Delving deeper, I put a console.log() on the Component.onCompleted for both the ListView and the Delegate to output their widths.

      Case 1 widths

      qml: Delegate 0: -30
      qml: Delegate 1: -30
      qml: Delegate 2: -30
      qml: Delegate 3: -30
      qml: Delegate 4: -30
      qml: Delegate 5: -30
      qml: Delegate 6: -30
      qml: Delegate 7: -30
      qml: Delegate 8: -30
      qml: Delegate 9: -30
      qml: Delegate 10: -30
      qml: Delegate 11: -30
      qml: Delegate 12: -30
      qml: Delegate 13: -30
      qml: Delegate 14: -30
      qml: Delegate 15: -30
      qml: Delegate 16: -30
      qml: Delegate 17: -30
      qml: Delegate 18: -30
      qml: Delegate 19: -30
      qml: Delegate 10: 70
      qml: Delegate 11: 70
      qml: Delegate 12: 70
      qml: Delegate 13: 70
      qml: Delegate 14: 70
      qml: Delegate 15: 70
      qml: Delegate 16: 70
      qml: Delegate 17: 70
      qml: Delegate 18: 70
      qml: Delegate 1: 70
      qml: Delegate 2: 70
      qml: Delegate 3: 70
      qml: Delegate 4: 70
      qml: Delegate 5: 70
      qml: Delegate 6: 70
      qml: Delegate 7: 70
      qml: Delegate 8: 70
      qml: ListView: 560
      qml: Delegate 9: 70
      qml: Delegate 10: 70
      qml: Delegate 11: 70
      qml: Delegate 12: 70
      

      Case 2 widths

      qml: Delegate 0: -30
      qml: Delegate 1: -30
      qml: Delegate 2: -30
      qml: Delegate 3: -30
      qml: Delegate 4: -30
      qml: Delegate 5: -30
      qml: Delegate 6: -30
      qml: Delegate 7: -30
      qml: Delegate 8: -30
      qml: Delegate 9: -30
      qml: Delegate 10: -30
      qml: Delegate 11: -30
      qml: Delegate 12: -30
      qml: Delegate 13: -30
      qml: Delegate 14: -30
      qml: Delegate 15: -30
      qml: Delegate 16: -30
      qml: Delegate 17: -30
      qml: Delegate 18: -30
      qml: Delegate 19: -30
      qml: ListView: 560
      
      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      @paulmasri said in Strange ListView behaviour (depending on types of anchors):

      anchors.width: parent.width
      anchors.height: parent.height

      there is no such thing as anchors.width or height, there's only left, horizontalCenter, right, top, verticalCenter, baseline, and bottom

      if this actually compiles/loads, than its probably undefined/ignored and your actual ListView has no width or height set. -> it is 0 or derived from the content


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      P 1 Reply Last reply
      0
      • P Offline
        P Offline
        paulmasri
        wrote on last edited by
        #3

        NB: If I make the Delegate width bind to an expression based on the width of the parent of ListView, then the behaviour is the same as if I had used a hardcoded number: all delegates instantly get the correct width (no initial setting to -30).

        1 Reply Last reply
        0
        • J.HilkJ J.Hilk

          @paulmasri said in Strange ListView behaviour (depending on types of anchors):

          anchors.width: parent.width
          anchors.height: parent.height

          there is no such thing as anchors.width or height, there's only left, horizontalCenter, right, top, verticalCenter, baseline, and bottom

          if this actually compiles/loads, than its probably undefined/ignored and your actual ListView has no width or height set. -> it is 0 or derived from the content

          P Offline
          P Offline
          paulmasri
          wrote on last edited by paulmasri
          #4

          @J-Hilk said in Strange ListView behaviour (depending on types of anchors):

          @paulmasri said in Strange ListView behaviour (depending on types of anchors):

          anchors.width: parent.width
          anchors.height: parent.height

          there is no such thing as anchors.width or height, there's only left, horizontalCenter, right, top, verticalCenter, baseline, and bottom

          if this actually compiles/loads, than its probably undefined/ignored and your actual ListView has no width or height set. -> it is 0 or derived from the content

          Sorry that's a typo in my code above: I actually used width: parent.width and height: parent.height.

          Just corrected the OP.

          1 Reply Last reply
          1
          • J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #5

            @paulmasri alright

            I tried your 2nd example

            46591995-674b-4f68-b05e-eb29bcbd57a9-image.png

            and it seems to be working perfectly fine ?

            do you have any runtime warnings in your program, that would indicate a property binding break?

            tried with Qt 5.15.10 on macOS


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            P 2 Replies Last reply
            0
            • J.HilkJ J.Hilk

              @paulmasri alright

              I tried your 2nd example

              46591995-674b-4f68-b05e-eb29bcbd57a9-image.png

              and it seems to be working perfectly fine ?

              do you have any runtime warnings in your program, that would indicate a property binding break?

              tried with Qt 5.15.10 on macOS

              P Offline
              P Offline
              paulmasri
              wrote on last edited by
              #6

              @J-Hilk said in Strange ListView behaviour (depending on types of anchors):

              @paulmasri alright

              I tried your 2nd example

              46591995-674b-4f68-b05e-eb29bcbd57a9-image.png

              and it seems to be working perfectly fine ?

              do you have any runtime warnings in your program, that would indicate a property binding break?

              tried with Qt 5.15.10 on macOS

              Strange. Thanks for checking that. I'm using Qt 6.2.3 on macOS with Apple clang version 13.0.0 (clang-1300.0.29.30), but I've had this issue previously when I was using Qt 5.9. (At the time I used a hack to get around it but I want to solve it properly now.)

              Let me try playing with the parent to see if I can get something you can reproduce.

              1 Reply Last reply
              0
              • J.HilkJ J.Hilk

                @paulmasri alright

                I tried your 2nd example

                46591995-674b-4f68-b05e-eb29bcbd57a9-image.png

                and it seems to be working perfectly fine ?

                do you have any runtime warnings in your program, that would indicate a property binding break?

                tried with Qt 5.15.10 on macOS

                P Offline
                P Offline
                paulmasri
                wrote on last edited by
                #7

                @J-Hilk OK, the following is my minimal complete example. Please could you try the following:

                main.qml

                Window { id: root
                    width: 800
                    height: 600
                    visible: true
                
                    Item { id: container
                        anchors.left: parent.left
                        anchors.top: parent.top
                        width: parent.width - 40
                        height: 200
                
                        ListView { id: listview
                            anchors.left: parent.left
                            anchors.top: parent.top
                            width: parent.width
                            height: parent.height
                            orientation: Qt.Horizontal
                
                            model: 20
                            delegate: Rectangle {
                                width: listview.width / 8
                                height: listview.height
                                border.color: "lightblue"
                                border.width: 1
                
                                Text {
                                    anchors.fill: parent
                                    horizontalAlignment: Text.AlignHCenter
                                    verticalAlignment: Text.AlignVCenter
                                    text: model.index
                                }
                
                                Component.onCompleted: console.log("Delegate "+model.index+": "+width)
                                onWidthChanged: console.log("Delegate "+model.index+": "+width+" changed")
                            }
                
                            Component.onCompleted: { positionViewAtBeginning(); console.log("ListView: "+width)                 
                        }
                    }
                }
                

                I've directly copy/pasted this so it should be error free.

                My odd scenario seems to be dependent on all of the following being in place:

                • delegate width is an expression using ListView width
                • ListView sets left, top, width & height (to match parent) instead of using anchors.fill: parent
                • ListView sits within a container
                • The container width is an expression using parent.width (but not simply : parent.width)
                • The container width is a numerical value

                That's a weird set of constraints. My suspicion now is that this triggers a long-standing bug, but it would be good to get this reproduced by someone else.

                J.HilkJ 1 Reply Last reply
                1
                • P paulmasri

                  @J-Hilk OK, the following is my minimal complete example. Please could you try the following:

                  main.qml

                  Window { id: root
                      width: 800
                      height: 600
                      visible: true
                  
                      Item { id: container
                          anchors.left: parent.left
                          anchors.top: parent.top
                          width: parent.width - 40
                          height: 200
                  
                          ListView { id: listview
                              anchors.left: parent.left
                              anchors.top: parent.top
                              width: parent.width
                              height: parent.height
                              orientation: Qt.Horizontal
                  
                              model: 20
                              delegate: Rectangle {
                                  width: listview.width / 8
                                  height: listview.height
                                  border.color: "lightblue"
                                  border.width: 1
                  
                                  Text {
                                      anchors.fill: parent
                                      horizontalAlignment: Text.AlignHCenter
                                      verticalAlignment: Text.AlignVCenter
                                      text: model.index
                                  }
                  
                                  Component.onCompleted: console.log("Delegate "+model.index+": "+width)
                                  onWidthChanged: console.log("Delegate "+model.index+": "+width+" changed")
                              }
                  
                              Component.onCompleted: { positionViewAtBeginning(); console.log("ListView: "+width)                 
                          }
                      }
                  }
                  

                  I've directly copy/pasted this so it should be error free.

                  My odd scenario seems to be dependent on all of the following being in place:

                  • delegate width is an expression using ListView width
                  • ListView sets left, top, width & height (to match parent) instead of using anchors.fill: parent
                  • ListView sits within a container
                  • The container width is an expression using parent.width (but not simply : parent.width)
                  • The container width is a numerical value

                  That's a weird set of constraints. My suspicion now is that this triggers a long-standing bug, but it would be good to get this reproduced by someone else.

                  J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote on last edited by J.Hilk
                  #8

                  @paulmasri ok!

                  first of, there is a } missing but I was able to fix that! 😉

                  I get the following result:

                  f47130cb-3a56-4a6f-90c1-9984a8a660af-image.png

                  qml: Delegate 0: -5 changed
                  qml: Delegate 0: -5
                  qml: Delegate 1: -5 changed
                  qml: Delegate 1: -5
                  qml: Delegate 2: -5 changed
                  qml: Delegate 2: -5
                  qml: Delegate 3: -5 changed
                  qml: Delegate 3: -5
                  qml: Delegate 4: -5 changed
                  qml: Delegate 4: -5
                  qml: Delegate 5: -5 changed
                  qml: Delegate 5: -5
                  qml: Delegate 6: -5 changed
                  qml: Delegate 6: -5
                  qml: Delegate 7: -5 changed
                  qml: Delegate 7: -5
                  qml: Delegate 8: -5 changed
                  qml: Delegate 8: -5
                  qml: Delegate 9: -5 changed
                  qml: Delegate 9: -5
                  qml: Delegate 10: -5 changed
                  qml: Delegate 10: -5
                  qml: Delegate 11: -5 changed
                  qml: Delegate 11: -5
                  qml: Delegate 12: -5 changed
                  qml: Delegate 12: -5
                  qml: Delegate 13: -5 changed
                  qml: Delegate 13: -5
                  qml: Delegate 14: -5 changed
                  qml: Delegate 14: -5
                  qml: Delegate 15: -5 changed
                  qml: Delegate 15: -5
                  qml: Delegate 16: -5 changed
                  qml: Delegate 16: -5
                  qml: Delegate 17: -5 changed
                  qml: Delegate 17: -5
                  qml: Delegate 18: -5 changed
                  qml: Delegate 18: -5
                  qml: Delegate 19: -5 changed
                  qml: Delegate 19: -5
                  qml: Delegate 0: 95 changed
                  qml: Delegate 1: 95 changed
                  qml: Delegate 2: 95 changed
                  qml: Delegate 3: 95 changed
                  qml: Delegate 4: 95 changed
                  qml: Delegate 5: 95 changed
                  qml: Delegate 6: 95 changed
                  qml: Delegate 7: 95 changed
                  qml: Delegate 8: 95 changed
                  qml: Delegate 9: 95 changed
                  qml: Delegate 10: 95 changed
                  qml: Delegate 11: 95 changed
                  qml: Delegate 12: 95 changed
                  qml: Delegate 13: 95 changed
                  qml: Delegate 14: 95 changed
                  qml: Delegate 15: 95 changed
                  qml: Delegate 16: 95 changed
                  qml: Delegate 17: 95 changed
                  qml: Delegate 18: 95 changed
                  qml: Delegate 19: 95 changed
                  qml: ListView: 760
                  

                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  P 1 Reply Last reply
                  0
                  • J.HilkJ J.Hilk

                    @paulmasri ok!

                    first of, there is a } missing but I was able to fix that! 😉

                    I get the following result:

                    f47130cb-3a56-4a6f-90c1-9984a8a660af-image.png

                    qml: Delegate 0: -5 changed
                    qml: Delegate 0: -5
                    qml: Delegate 1: -5 changed
                    qml: Delegate 1: -5
                    qml: Delegate 2: -5 changed
                    qml: Delegate 2: -5
                    qml: Delegate 3: -5 changed
                    qml: Delegate 3: -5
                    qml: Delegate 4: -5 changed
                    qml: Delegate 4: -5
                    qml: Delegate 5: -5 changed
                    qml: Delegate 5: -5
                    qml: Delegate 6: -5 changed
                    qml: Delegate 6: -5
                    qml: Delegate 7: -5 changed
                    qml: Delegate 7: -5
                    qml: Delegate 8: -5 changed
                    qml: Delegate 8: -5
                    qml: Delegate 9: -5 changed
                    qml: Delegate 9: -5
                    qml: Delegate 10: -5 changed
                    qml: Delegate 10: -5
                    qml: Delegate 11: -5 changed
                    qml: Delegate 11: -5
                    qml: Delegate 12: -5 changed
                    qml: Delegate 12: -5
                    qml: Delegate 13: -5 changed
                    qml: Delegate 13: -5
                    qml: Delegate 14: -5 changed
                    qml: Delegate 14: -5
                    qml: Delegate 15: -5 changed
                    qml: Delegate 15: -5
                    qml: Delegate 16: -5 changed
                    qml: Delegate 16: -5
                    qml: Delegate 17: -5 changed
                    qml: Delegate 17: -5
                    qml: Delegate 18: -5 changed
                    qml: Delegate 18: -5
                    qml: Delegate 19: -5 changed
                    qml: Delegate 19: -5
                    qml: Delegate 0: 95 changed
                    qml: Delegate 1: 95 changed
                    qml: Delegate 2: 95 changed
                    qml: Delegate 3: 95 changed
                    qml: Delegate 4: 95 changed
                    qml: Delegate 5: 95 changed
                    qml: Delegate 6: 95 changed
                    qml: Delegate 7: 95 changed
                    qml: Delegate 8: 95 changed
                    qml: Delegate 9: 95 changed
                    qml: Delegate 10: 95 changed
                    qml: Delegate 11: 95 changed
                    qml: Delegate 12: 95 changed
                    qml: Delegate 13: 95 changed
                    qml: Delegate 14: 95 changed
                    qml: Delegate 15: 95 changed
                    qml: Delegate 16: 95 changed
                    qml: Delegate 17: 95 changed
                    qml: Delegate 18: 95 changed
                    qml: Delegate 19: 95 changed
                    qml: ListView: 760
                    
                    P Offline
                    P Offline
                    paulmasri
                    wrote on last edited by
                    #9

                    @J-Hilk said in Strange ListView behaviour (depending on types of anchors):

                    @paulmasri ok!

                    first of, there is a } missing but I was able to fix that! 😉

                    The Component.onCompleted. D'oh! My bad.

                    And of course there needs to be an import QtQuick at the top for Qt 6.2. Or import QtQuick 2.12 and import QtQuick.Window 2.15 for Qt 5.X.

                    I get the following result:
                    ...

                    That's so weird. Here's my screenshot for the exact same code.

                    Screenshot 2022-09-14 at 14.25.55.png

                    And in my console output, when it changes the delegates to 95, mine happened to do them in reverse order, not that that should have any impact.

                    I think I'll log this as a bug.

                    1 Reply Last reply
                    1
                    • P Offline
                      P Offline
                      paulmasri
                      wrote on last edited by
                      #10

                      Reported: https://bugreports.qt.io/browse/QTBUG-106624

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt
                      • Unsolved