Reputation: 3174
I've been trying to create a function that programmatically scrolls to bottom a ScrollView using Qt Quick Controls 2. I've tried various options, but much of the support I found online refers to Qt Quick Controls 1, not 2. This is what I've tried:
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()
}
}
}
Does anyone know how this can be achieved using Qt Quick Controls 2? If no, does anyone have any alternatives to this approach?
Upvotes: 3
Views: 1865
Reputation: 8399
You are trying to set the ScrollBar
's position to 1.0
:
chatView.ScrollBar.position = 0.0 // Tried also with 1.0
however, you do not consider its size.
Take into account the size of the ScrollBar
when you set its position like this:
chatView.ScrollBar.vertical.position = 1.0 - chatView.ScrollBar.vertical.size
I was curious of how Qt itself solves this problem, so I took a look at how QQuickScrollBar::increase()
is implemented and I saw this line:
setPosition(qMin<qreal>(1.0 - d->size, d->position + step));
Then I took the first argument of qMin
, i.e. 1.0 - d->size
, and the solution was clear.
Since you did not provide a MCE, I wrote one myself. I hope you can adapt it for your particullar case. Here it is:
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()
}
}
The example produces the following result:
Upvotes: 7