How to scroll QML ScrollView to center?

10,011

Solution 1

Despite the appearence, ScrollView is tightly related to Flickable. Indeed, Flickable is used to control the visible area. Such an Item is available as the (readonly) property flickableItem. Flickable has the contentX and contentY properties to control the current visible area. These properties can be combined with the width and height of the ScrollView to position the visible area exactly at the center. Typically you have:

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

The difference is necessary since the first calls just moves the center to the top left point of the visible area (where contentX/contentY are located).

Here is a complete example with an Image as main child of the ScrollView.

Disclaimer: In the simple scenario proposed by the example, with a remotelly loaded image, sizes can still be unset when onCompleted is called, resulting in a centering code that doesn't work. By setting widths and heigths directly into code the problem is avoided. In a real scenario such detail should be unnecessary.

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Controls 1.2

Window {
    id: main
    visible: true
    width: 600; height: 350

    ScrollView {
        id: ss
        width: 600
        height: 350

        Image {
            id: name
            width: 900
            height: 600
            source: "http://www.joomlaworks.net/images/demos/galleries/abstract/7.jpg"
        }

        Component.onCompleted: {
            flickableItem.contentY = flickableItem.contentHeight / 2 - height / 2
            flickableItem.contentX = flickableItem.contentWidth / 2 - width / 2
        }
    }
}

Solution 2

Here is a solution for QQC2. Tested on Qt 5.12.

The solution is simple, just store the scrollBar pointer and control it however you want.

ScrollView2.qml

import QtQuick 2.0
import QtQuick.Controls 2.4

ScrollView {
    id: root
    property ScrollBar hScrollBar: ScrollBar.horizontal
    property ScrollBar vScrollBar: ScrollBar.vertical

    /**
     * @param type [Qt.Horizontal, Qt.Vertical]
     * @param ratio 0.0 to 1.0
     */
    function scrollTo(type, ratio) {
        var scrollFunc = function (bar, ratio) {
            bar.setPosition(ratio - bar.size/2)
        }
        switch(type) {
        case Qt.Horizontal:
            scrollFunc(root.hScrollBar, ratio)
            break;
        case Qt.Vertical:
            scrollFunc(root.vScrollBar, ratio)
            break;
        }
    }
}

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 500
    height: 500
    ScrollView2 {
        id: scroll
        anchors.fill: parent
        Text {
            width: 1000
            height: 1000
            text: "ABC"
            font.pixelSize: 800
            Component.onCompleted: {
                scroll.scrollTo(Qt.Horizontal, 0.5)
                scroll.scrollTo(Qt.Vertical, 0.5)
            }
        }
    }
}

Solution 3

Since Qt 5.14 (maybe already in 5.12) you can now simply do:

ScrollView {
    Component.onCompleted {
        // scroll to vertical center
        ScrollBar.vertical.position = 0.5
    }

    // put your content item here:
    Image {
        // …
    }
}
Share:
10,011
fhdnsYa
Author by

fhdnsYa

Updated on July 23, 2022

Comments

  • fhdnsYa
    fhdnsYa almost 2 years

    I have code like this:

    ScrollView {
        Image {
            source: "..."
        }
    }
    

    Image is higher than the ScrollView. How can I scroll the latter to the center of Image element?

  • Vadim Peretokin
    Vadim Peretokin about 5 years
    Is there a way to do this with Quick Controls 2?
  • JustWe
    JustWe over 4 years
    @VadimPeretokin take look my answer : )