I have a problem with centering QML objects in a ScrollView. I want to scroll the images and other QML elements and they should be centered. But they are always sticked to the top left angle.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Window 2.0
ApplicationWindow{
id: appWindow
width:Screen.width
height:Screen.height
visible: true
ScrollView {
anchors.fill: parent
Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
width: 800
height: 800
color : "yellow"
}
}
}
You have two aspects to take in account. Directly from the docs:
Only one Item can be a direct child of the ScrollView and the child is implicitly anchored to fill the scroll view.
So you could not have more than one Rectangle, just a container for all the Rectangles (which actually are images, as stated in your question).
Moreover, it should be noted, again from the docs, that:
The width and height of the child item will be used to define the size of the content area.
Hence, you need only one child for the ScrollView and ensure that it takes the correct size from the parent. I would use a ColumnLayout for the purpose. Final sample code here:
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Window 2.0
import QtQuick.Layouts 1.1
ApplicationWindow{
id: appWindow
width: 200
height: 100
visible: true
ScrollView {
anchors.fill: parent
ColumnLayout { // unique child
spacing: 10
width: appWindow.width // ensure correct width
height: children.height // ensure correct height
// your children hereon...
Repeater {
model: 4
delegate: Rectangle {
Layout.alignment: Qt.AlignHCenter
width: 50
height: 50
color : "yellow"
}
}
}
}
}
According to the OP, the provided solution does not perfectly meet his needs, and that's pretty reasonable. In particular:
Both the problems are related to the approach used. Problem 1 is caused by the binding between the parent width and the ScrollView width: since the visible width is always equal to the total width, no horizontal scroll is shown, even if the contained items are larger than the window. Problem 2 is a consequence of the 1: since the width is equal to application, as soon as a vertical scrollbar is added, the horizontal one is also added to show the horizontal space covered by the vertical scrollbar.
Both the problems can be solved by changing the width binding to be either equal to the contained items width (to solve problem 1) or equal to the width of the viewport (solve problem 2), as also discussed in this other answer. Finally, anchoring should be removed to avoid binding loops. Here is a complete example working as expected:
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
ApplicationWindow{
id: appWindow
width: 200
height: 100
visible: true
ScrollView {
id: scroller
width: appWindow.width // NO ANCHORING TO AVOID binding loops!
height: appWindow.height
ColumnLayout { // <--- unique child
spacing: 10
width: Math.max(scroller.viewport.width, implicitWidth) // ensure correct width
height: children.height // ensure correct height
// your children hereon...
Repeater {
model: 3
delegate: Rectangle {
Layout.alignment: Qt.AlignHCenter
width: 150
height: 150
color : "yellow"
}
}
}
}
}
is bound to the window width horizontal scrolls are not shown, even if contained items are larger than the window.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With