QML TextArea 滚动事件

QML TextArea scroll events

有没有办法知道 TextArea 滚动条到达顶部或底部?我想在聊天客户端中实现动态文本加载:当用户滚动到顶部时,更多文本会添加到文档中。像这样(伪代码):

import QtQuick 2.4
import QtQuick.Controls 1.2

TextArea {
      id: chat
      onScrolledToTop: text = loadMoreText() + text
}

Textarea继承自ScrollView,后者有一个Flickable项来控制可见区域。这样的项目作为(只读)属性 flickableItem 可用。在其他属性中,Flickable 提供了 contentY:

These properties hold the surface coordinate currently at the top-left corner of the Flickable. For example, if you flick an image up 100 pixels, contentY will be 100.

因此您可以检查此 属性 更改,一旦达到某个阈值,就更新您的文本。请注意,您应该在设置文本后调整 contentY 以模拟添加。否则显示的文本将与刚添加的文本完全相同。 OP 提出的一个不错的方法是保存原始 contentHeight 并将 contentY 设置为更新后的 contentHeight 和保存的 contentHeight 之间的差异 - 同时考虑应用 threshold.

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 1.3

Window {
    visible: true
    width: 400
    height: 200

    TextArea {
        id: chat
        anchors.fill: parent
        property int threshold: 10

        text: "Current\ntext\n\to\nmove\ndown\ndown\ndown
               \ndown\ndown\ndown\ndown\ndown\ndown\ndown"
        Component.onCompleted: cursorPosition = text.length


        flickableItem.onContentYChanged: {
            if(flickableItem.contentY <= threshold) {
                var oldHeight = flickableItem.contentHeight
                text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit,
                            sed do eiusmod tempor incididunt ut labore et dolore magna
                            aliqua." + text
                flickableItem.contentY = threshold + flickableItem.contentHeight - oldHeight  // leave flickable in old position
            }
        }
    }
}
ScrollView {
        width: root.width - ((root.width/10) * 2) - (root.width/15)*2
        x:  (root.width/10) + root.width/15
        height: root.height - (root.height/5)
        clip: true

        TextArea {
            id: textArea
            clip: true
            width: root.width - ((root.width/10) * 2) - (root.width/15)*2
            height: root.height - (root.height/5)
            wrapMode: "WrapAtWordBoundaryOrAnywhere"
            placeholderText: "inter description"
        }
    }