Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Center elements inside Scrollview

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"
        }
    }
}
like image 473
ningen Avatar asked Feb 25 '26 23:02

ningen


1 Answers

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:

  1. no horizontal scrollbar is shown if the window is resized horizontally
  2. the horizontal scrollbar is shown as soon as the vertical one is shown

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.

like image 62
BaCaRoZzo Avatar answered Feb 28 '26 20:02

BaCaRoZzo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!