如何访问 QML ScrollView 的移动已经结束?

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

我想在 QML ScrollView 的滚动结束时做一些事情。从文档中我假设 flickableItem.onMovementEnded 是我正在寻找的,但我从来没有得到那个信号。我理解 "Movement" 错了吗? 我已经编写了这个最小的 QML 应用程序,但我的 console.log 从未被调用过。我 运行 在 Mac 上使用 Qt 5.7 或 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
        }
    }

}

我也尝试通过 "Connections" 连接它,但没有成功。

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

来自文档:

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.

我觉得 flickableItem 属性 只有在滚动视图与 Flickable 结合使用时才会被填充。在你的代码中它不是。

编辑:经过一些调查,我发现 属性 存在,即使您不使用 Flickable,但信号将 如果你在 ScrollView 中有一个实际的 Flickable 并且当你从上到下快速滚动时它只会 被发射 或返回使用鼠标滚轮,轻弹不会这样做,使用滚动条不会这样做。不理想,有点马车...

看来您真正想要的是只使用 Flickable 并在其上手动放置滚动条,有很多示例可以做到这一点。然后它总是在停止时发出。

根据@ddriver 的输入,我使用 onContentYChanged 和计时器构建了一个解决方案。这对我来说已经足够了,尽管它并不完美。

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")
        }
    }

}