Как программно прокрутить ScrollView вниз?

#qt #qml #qtquick2 #qtquickcontrols2

#qt #qml #qtquick2 #qtquickcontrols2

Вопрос:

Я пытался создать функцию, которая программно прокручивает ScrollView вниз, используя Qt Quick Controls 2. Я пробовал различные варианты, но большая часть поддержки, которую я нашел в Интернете, относится к Qt Quick Controls 1, а не 2. Это то, что я пробовал:

 import QtQuick 2.8
import QtQuick.Controls 2.4

ScrollView {
    id: chatView

    anchors.top: parent.top
    anchors.left: parent.left
    anchors.right: parent.right
    anchors.bottom: inputTextAreaContainer.top

    function scrollToBottom() {
        // Try #1
//      chatView.contentItem.contentY = chatBox.height - chatView.contentItem.height
//      console.log(chatView.contentItem.contentY)

        // Try #2
//      flickableItem.contentY = flickableItem.contentHeight / 2 - height / 2
//      flickableItem.contentX = flickableItem.contentWidth / 2 - width / 2

        // Try #3
        chatView.ScrollBar.position = 0.0 // Tried also with 1.0
    }

    TextArea {
        id: chatBox
        anchors.fill: parent
        textFormat: TextArea.RichText
        onTextChanged: {
            // Here I need to scroll
            chatView.scrollToBottom()
        }
    }
}
  

Кто-нибудь знает, как этого можно достичь с помощью Qt Quick Controls 2?
Если нет, есть ли у кого-нибудь альтернативы этому подходу?

Ответ №1:

Причина

Вы пытаетесь установить положение ScrollBar ‘s в 1.0 :

 chatView.ScrollBar.position = 0.0 // Tried also with 1.0
  

однако вы не учитываете его размер.

Решение

Примите во внимание размер ScrollBar , когда вы устанавливаете его положение следующим образом:

 chatView.ScrollBar.vertical.position = 1.0 - chatView.ScrollBar.vertical.size
  

Как я пришел к этому решению?

Мне было любопытно, как сам Qt решает эту проблему, поэтому я взглянул на то, как QQuickScrollBar::increase() это реализовано, и я увидел эту строку:

 setPosition(qMin<qreal>(1.0 - d->size, d->position   step));
  

Затем я принял первый аргумент qMin , т. Е. 1.0 - d->size и решение было ясным.

Пример

Поскольку вы не предоставили MCE, я написал его сам. Я надеюсь, вы сможете адаптировать его для вашего конкретного случая. Вот оно:

 import QtQuick 2.8
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.12

ApplicationWindow {
    width: 480
    height: 640
    visible: true
    title: qsTr("Scroll To Bottom")

    ColumnLayout {
        anchors.fill: parent

        ScrollView {
            id: scrollView

            Layout.fillWidth: true
            Layout.fillHeight: true

            function scrollToBottom() {
                ScrollBar.vertical.position = 1.0 - ScrollBar.vertical.size
            }

            contentWidth: children.implicitWidth
            contentHeight: children.implicitHeight
            ScrollBar.vertical.policy: ScrollBar.AlwaysOn
            clip: true

            ColumnLayout {

                Layout.fillWidth: true
                Layout.fillHeight: true

                Repeater {
                    model: 50

                    Label {
                        text: "Message: "   index
                    }
                }
            }
        }

        TextField {
            Layout.fillWidth: true
        }
    }

    Component.onCompleted: {
        scrollView.scrollToBottom()
    }
}
  

Результат

Пример дает следующий результат:

Окно со списком, прокручиваемое до самого низа