QML: ListView behaves weird when elements exceed 40 elements

130 Views Asked by At

I am using Qt 5.2.1 and I have a custom scrollbar.

import QtQuick 1.1

Item {
    id: root
    property variant flickable: parent
    property int rightSpacing: 5
    property int scrollStep: 25
    anchors.top: parent.top
    //anchors.topMargin: -50
    anchors.bottom: parent.bottom
    anchors.right: parent.right
    width: 16
    z: 4

    Rectangle {
        id: up
        anchors.top: parent.top
        anchors.right: parent.right
        anchors.rightMargin: rightSpacing
        visible: scrollbar.visible

        color: "dark grey"
        height: 16
        width: 16
        border.width: 1
        border.color: "black"

        MouseArea {
            anchors.fill: parent

            Image {
                anchors.verticalCenter: parent.verticalCenter
                anchors.horizontalCenter: parent.horizontalCenter
                anchors.horizontalCenterOffset: 0.5

                source: theme.location + "triangle.png"
                height: 11
                width: 11
                fillMode: Image.PreserveAspectFit
            }

            onClicked: {

                if((flickable.contentY - scrollStep) <= 0) {
                    flickable.contentY = 0
                }
                else {
                    flickable.contentY = flickable.contentY - scrollStep
                }
            }

            onReleased: {
                up.color = "dark grey"
            }

            onPressed: {
                up.color = "light grey"
            }
        }
    }

    Rectangle {
        id: scrollbar


        anchors.top: parent.top
        anchors.bottom: parent.bottom
        anchors.right: parent.right

        anchors.topMargin: 16
        anchors.bottomMargin: 16
        anchors.rightMargin: rightSpacing

        width: 16//0.03 * parent.width
        radius: 0//0.5 * width
        color: "lightgrey"
        visible: flickable.visibleArea.heightRatio < 1.0
        clip: true

        border.width: 1
        border.color: "black"

        Rectangle {
            id: handle
            width: parent.width
            height: flickable.visibleArea.heightRatio * scrollbar.height
            color: "dark grey"
            opacity: clicker.drag.active ? 0.7 : 0.4
            radius: 0//0.5 * width
            border.width: 1
            border.color: "black"

        }

        Binding {
            target: handle
            property: "y"
            value: flickable.visibleArea.yPosition * scrollbar.height
            when: !clicker.pressed
        }

        MouseArea {
            id: clicker
            anchors.fill: parent

            drag {
                target: handle
                minimumY: 0
                maximumY: scrollbar.height - handle.height
                axis: Drag.YAxis
            }

            onMouseYChanged: {
                flickable.contentY = handle.y / drag.maximumY * (flickable.contentHeight - flickable.height)
            }

            onClicked: {
                flickable.contentY = mouse.y / scrollbar.height * (flickable.contentHeight - flickable.height)
            }
        }
    }

    Rectangle {
        id: down
        anchors.bottom: parent.bottom
        anchors.right: parent.right
        anchors.rightMargin: rightSpacing
        visible: scrollbar.visible

        color: "dark grey"
        height: 16
        width: 16
        border.width: 1
        border.color: "black"

        MouseArea {
            anchors.fill: parent

            Image {
                anchors.verticalCenter: parent.verticalCenter
                anchors.horizontalCenter: parent.horizontalCenter
                anchors.horizontalCenterOffset: 0.5

                source: theme.location + "triangle.png"
                height: 11
                width: 11
                fillMode: Image.PreserveAspectFit

                rotation: 180
            }

            onClicked: {
                if((flickable.contentY + scrollStep) > (flickable.contentHeight - flickable.height)) {
                    flickable.contentY = (flickable.contentHeight - flickable.height)
                }
                else {
                    flickable.contentY = flickable.contentY + scrollStep
                }
            }

            onReleased: {
                down.color = "dark grey"
            }

            onPressed: {
                down.color = "light grey"
            }
        }
    }
}

This the how the scroll bar is used with the ListView

        ListView
        {
            id: listView
            focus: elist.activeWindow
            anchors.top: listHeader.bottom
            anchors.topMargin: 2
            anchors.bottom: parent.bottom
            anchors.bottomMargin: details.visible ? 210 : 1
            width: parent.width
            model: eventProxyModel
            delegate: delListItem
            highlight: delListHighlight
            highlightMoveDuration: 0
            highlightFollowsCurrentItem: true
            property bool sortOrder: false
            interactive: false
            boundsBehavior: Flickable.StopAtBounds
            snapMode: ListView.SnapToItem
            clip: true

            VScrollBar {
                id: listScrollBar
                anchors.rightMargin: -5
                anchors.bottomMargin: 1
            }
        }

The problem is that when about 40 items are more are inserted into the model. I have a script that inserts a lot of elements and I can scroll to the top and bottom and everything behaves just fine. When I go to insert 1 more item and scroll up the top element is missing and can scroll up to view it. When I scroll to the bottom there is an empty space at the bottom of the ListView. I can also use the handle to scroll past the bottom and the ListView will continue to scroll past the boundary. If I keep adding elements, top elements are not accessible and the bottom becomes bigger with empty elements and the scrollable area becomes larger.

I've been going at for days and would like some guidance on what may be causing this behavior, thank you.

0

There are 0 best solutions below