Strange ListView behaviour (depending on types of anchors)
-
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: parentwhile the other is positioned usingparent.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.

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.

Delving deeper, I put a
console.log()on theComponent.onCompletedfor both theListViewand theDelegateto 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: 70Case 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 -
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: parentwhile the other is positioned usingparent.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.

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.

Delving deeper, I put a
console.log()on theComponent.onCompletedfor both theListViewand theDelegateto 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: 70Case 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@paulmasri said in Strange ListView behaviour (depending on types of anchors):
anchors.width: parent.width
anchors.height: parent.heightthere is no such thing as anchors.width or height, there's only
left, horizontalCenter, right, top, verticalCenter, baseline, and bottomif 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
-
-
@paulmasri said in Strange ListView behaviour (depending on types of anchors):
anchors.width: parent.width
anchors.height: parent.heightthere is no such thing as anchors.width or height, there's only
left, horizontalCenter, right, top, verticalCenter, baseline, and bottomif 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
@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.heightthere is no such thing as anchors.width or height, there's only
left, horizontalCenter, right, top, verticalCenter, baseline, and bottomif 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.widthandheight: parent.height.Just corrected the OP.
-
@paulmasri alright
I tried your 2nd example

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
-
@paulmasri alright
I tried your 2nd example

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
@J-Hilk said in Strange ListView behaviour (depending on types of anchors):
@paulmasri alright
I tried your 2nd example

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.
-
@paulmasri alright
I tried your 2nd example

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
@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-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.
@paulmasri ok!
first of, there is a
}missing but I was able to fix that! 😉I get the following result:

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 -
@paulmasri ok!
first of, there is a
}missing but I was able to fix that! 😉I get the following result:

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@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 QtQuickat the top for Qt 6.2. Orimport QtQuick 2.12andimport QtQuick.Window 2.15for Qt 5.X.I get the following result:
...That's so weird. Here's my screenshot for the exact same code.

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.
-