pier_nasos
pier_nasos

Reputation: 678

QML ListView contentY property show an incorrect value after adding a new element to the beginning of the model

The situation arose using the C++ model, but it was also reproduced in pure QML.

  1. Full-page ListView component
  2. Delagat is the simplest, eliminating incorrect calculations - a rectangle of fixed height and width. Plus text for displaying the index of the element.
  3. The data model is set in QML from several values. In the example below, there are six of them.
  4. The form contains text with information about the current value of the contextY property in the ListView.
  5. There is a button on the form that adds a new element to the beginning of the model.

The essence of the problem. If the ListView is positioned on the first element, then adding a new element to the beginning of the model passes without an error.

If the ListView is scrolled so that the first element is not visible, then adding a new element to the beginning of the model leads to an incorrect (in my opinion) value of the contentY property. If we scroll the ListView to the beginning after adding a new element, we get contextY=-189 instead of the expected contextY=0. Where 189 is the height of the delegate.

I spent a lot of time finding a minimal example (

This effect is reproduced on Qt 5.14.2 when running on Windows and on Android.

import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Controls 2.12

Window {
    visible: true
    width: 379
    height: 680
    title: qsTr("Hello ListView ContentY")

    ListModel {
        id: idListModel
        ListElement { name: "A" }
        ListElement { name: "B" }
        ListElement { name: "C" }
        ListElement { name: "D" }
        ListElement { name: "E" }
        ListElement { name: "F" }
    }

    ListView {
        id: idRequestsListView
        anchors.fill: parent

        model: idListModel

        delegate: Rectangle {
            id: idRequestSmallCardMainRect
            height: 189
            width: parent.width
            color: "white"
            border.color: "gray"
            border.width: 1
            Text {
               x: 5
               text: "index: " + (model.index + 1) + " (" + model.name + ")"
               font.pixelSize: 18
            }
        }

        Text {
            anchors.left: parent.left
            anchors.leftMargin: 170
            text:     "contextY: "      + parent.contentY       + "\n"
                    + "contentHeight: " + parent.contentHeight + "\n"
                    + "count: "         + idListModel.count

            font.pixelSize: 15
            color: "blue"
        }
    }

    Button {
        anchors.centerIn: parent
        text: "prepend item"
        onClicked: {
            console.log("idListModel.size begin:", idListModel.count)
            idListModel.insert(0, { name: "G" })
            console.log("idListModel.size end:", idListModel.count)
        }
    }
}

app started scroll to second item press prepend button scroll to new first item

Upvotes: 0

Views: 1041

Answers (1)

JarMan
JarMan

Reputation: 8287

I understand you don't expect contentY to be -189, but really it needs to be looked at along with originY. The originY gets updated too when you add items to the list. And when you're scrolled to the top and you subtract contentY - originY, you should get 0. But their individual values can be arbitrary by themselves.

Upvotes: 2

Related Questions