How do I access that the movement of a QML ScrollView has ended?

4.1k Views Asked by At

I would like to do something the moment the scrolling of a QML ScrollView has ended. From the documentation I assume that flickableItem.onMovementEnded is what I'm looking for but I never get that signal. Am I understanding "Movement" wrong? I have written this minimal QML application and my console.log gets never called. I run this on a Mac with Qt 5.7 or 5.5.1.

import QtQuick 2.5
import QtQuick.Controls 1.4

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    ScrollView {
        id: scrollView

        anchors.fill: parent

        flickableItem.onMovementEnded: {
            console.log("onMovementEnded")
        }

        Rectangle {
            id: rect

            width: 3000
            height: 3000
        }
    }

}

I also tried to connect it via "Connections" with no luck.

Connections {
    target: scrollView.flickableItem
    onMovementEnded: {
        console.log("onMovementEnded")
    }
}
2

There are 2 best solutions below

0
philipp On BEST ANSWER

Based on @ddriver's input, I build a solution using onContentYChanged and a Timer. This is sufficient for me even though it is not perfect.

import QtQuick 2.5
import QtQuick.Controls 1.4

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    ScrollView {
        id: scrollView

        anchors.fill: parent

        flickableItem.onContentXChanged: {
            updateContentDelay.restart()
        }

        flickableItem.onContentYChanged: {
            updateContentDelay.restart()
        }

        Rectangle {
            id: rect

            width: 3000
            height: 3000
        }
    }

    Timer {
        id: updateContentDelay
        interval: 200
        repeat: false

        onTriggered: {
            console.log("do something")
        }
    }

}
2
dtech On

From the documentation:

A ScrollView can be used either to replace a Flickable or decorate an existing Flickable.

...

flickableItem : Item

The flickableItem of the ScrollView. If the contentItem provided to the ScrollView is a Flickable, it will be the contentItem.

Sounds to me that the flickableItem property will be populated only if the scroll view is used in conjunction with a Flickable. And in your code it is not.

EDIT: After investigating a little I found out that the property is there even if you don't use a Flickable, but the signal will only be emitted if you have an actual Flickable inside the ScrollView and it will only be emitted when you scroll quickly from all the way from top to bottom or back using the mouse wheel, flicking won't do it, using the scrollbar won't do it. Not ideal, kind of buggy...

Seems that what you really want is to just use a Flickable and put manually scrollbars on it, there are plenty of examples how to do it. And then it will always emit when it comes to a stop.