Search code examples
qtqmlqt5zoomingscale

Proper way to implement zoom/scale in Qt Quick (QML) Flickable


I'm using Qt 5.2 beta, Qt Quick 2.1.

I have straight ahead problem with Flickable component.

Here is minimal working code example:

import QtQuick 2.1
import QtQuick.Controls 1.0

ApplicationWindow {
    width: 300
    height: 200

    Rectangle {
        anchors.fill: parent
        color: "green"

        Flickable {
            id: flickArea
            anchors {fill: parent; margins: 10; }
            contentWidth: rect.width;
            contentHeight: rect.height
            Rectangle {
                id: rect
                x: 0; y: 0;
                width: 200; height: 300;
                color: "lightgrey"

                Rectangle {
                    anchors { fill: parent; margins: 10; }
                    color: "red"
                }
            }
        }
    }
    Button {
        anchors.bottom: parent.bottom;
        anchors.horizontalCenter: parent.horizontalCenter;
        text: "Scale flickArea"
        onClicked: { flickArea.scale += 0.2; }
    }
}

When I'm doing scaling, I expect that all child elements will stay visible as it was before and inner area to become bigger.

But instead, child elements move out of Flickable content.

Can someone propose a normal way to avoid this problem without the need for manual recalculation of all offsets?


Solution

  • I got it work as expected this way, but IMO this way is little bit tricky:

    import QtQuick 2.1
    import QtQuick.Controls 1.0
    
    ApplicationWindow {
        width: 300
        height: 200
    
        Rectangle {
            anchors.fill: parent
            color: "green"
    
            Flickable {
                id: flickArea
                anchors {fill: parent; margins: 10; }
                contentWidth: rect.width*rect.scale
                contentHeight: rect.height*rect.scale
                Rectangle {
                    id: rect
                    transformOrigin: Item.TopLeft
                    x: 0; y: 0;
                    width: 200; height: 300;
                    color: "lightgrey"
    
                    Rectangle {
                        id: inner
                        anchors { fill: parent; margins: 10; }
                        color: "red"
                    }
                }
            }
        }
        Button {
            anchors.bottom: parent.bottom;
            anchors.horizontalCenter: parent.horizontalCenter;
            text: "Scale flickArea"
            onClicked: {
                rect.scale += 0.2;
            }
        }
    }
    

    Can someone propose something better?

    UPD. I did not close this question for 1 year, but still didn't get any better solution or better way to doing things.