Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I scroll to the last item in a Flickable's Repeater

Tags:

qt

qml

qtquick2

I have a Flickable that is holding two Repeaters with a column layout. I am hoping to scroll to the last item in the first repeater. Is this possible?

I suppose one way could be to count how many items are in the first repeater and then multiply that by the height of the delegate I am using. (The delegate is a fixed height.) Or take the height of the repeater and subtract the height of the last delegate. etc... Though I am hoping on a better way than this.

import QtQuick 2.7
import QtQuick.Controls 2.0

Item {
    id:passwordsView
    Flickable {
        id: flickable1
        anchors.fill: parent
        contentHeight: passwordsView_column.height
        ScrollBar.vertical: ScrollBar { }
        Column {
            id:passwordsView_column
            spacing: 15
            anchors.left: parent.left
            anchors.right: parent.right
            Repeater {
                id: passwordsView_breadcrumb
                anchors.left: parent.left
                anchors.right: parent.right
                model: BreadcrumbModel {}
                delegate: PasswordFolderDelegate {
                    y: 8;
                    anchors.left: parent.left;
                    anchors.right: parent.right;
                }
            }

            Repeater {
                id: passwordsView_contents
                model: PasswordModel {}
                PasswordFolderDelegate {
                    y: 8
                    anchors.left: parent.left
                    anchors.right: parent.right
                }
                anchors.left: parent.left
                anchors.right: parent.right
            }
        }
    }
}
like image 679
Encompass Avatar asked Sep 06 '25 23:09

Encompass


1 Answers

Or take the height of the repeater and subtract the height of the last delegate.

Repeater doesn't have a height, as it merely positions the items, so that might be a little difficult.

The easiest approach I can think of is to use mapToItem():

import QtQuick 2.7
import QtQuick.Controls 2.0

ApplicationWindow {
    width: 400
    height: 400
    visible: true

    Flickable {
        id: flickable1
        anchors.fill: parent
        contentHeight: passwordsView_column.height
        ScrollBar.vertical: ScrollBar { }
        Column {
            id:passwordsView_column
            spacing: 15
            anchors.left: parent.left
            anchors.right: parent.right
            Repeater {
                id: passwordsView_breadcrumb
                anchors.left: parent.left
                anchors.right: parent.right
                model: 10
                delegate: Rectangle {
                    width: 50
                    height: 50
                    color: "transparent"
                    border.color: "salmon"

                    Text {
                        text: index
                        anchors.centerIn: parent
                    }
                }
            }

            Repeater {
                id: passwordsView_contents
                model: 10
                delegate: Rectangle {
                    width: 50
                    height: 50
                    color: "transparent"
                    border.color: "#444"

                    Text {
                        text: index
                        anchors.centerIn: parent
                    }
                }
            }
        }
    }

    Button {
        text: "Position at end"
        anchors.top: parent.top
        anchors.right: parent.right
        onClicked: {
            var lastItem = passwordsView_breadcrumb.itemAt(passwordsView_breadcrumb.count - 1);
            flickable1.contentY = lastItem.mapToItem(flickable1.contentItem, 0, 0).y
        }
    }
}

Note that this makes the view move instantly. If you want smooth scrolling, you'll probably have to calculate the required velocity somehow and pass it to flick().

like image 58
Mitch Avatar answered Sep 11 '25 22:09

Mitch