qtqmlpysideqtquick2qt-quick

How to scale a QML rectangle without also scaling any child text


I have the QML component outlined below. The problem I have is that when I scale the rectangle using a pinch area (which I want to happen), the text that is a child to that rectangle is also scaled (which I do not want to happen).

What is causing the text to scale? Given the Text has its scale property explicitly set to 1.0 as well as its font.pointSize, I can't understand why the text is changing at all.

How should one create text that is part of a scalable component, without the text itself scaling?

QML code:

import QtQuick 2

Rectangle {
    id: page
    width: 1000; height: 1000
    color: "black"

    Rectangle {
        id: image_boundary
        color: "green"
        width: 200
        height: 100
        x: (parent.width/2)-(image_boundary.width/2)
        y: (parent.height/2)-(image_boundary.height/2)

        onScaleChanged: {
            console.log("Scale changed:", scale)
        }

        PinchArea {
            anchors.fill: image_boundary
            property real initialScale: 1.0
            property real scale: 1.0
            id: pinch_area

            onPinchStarted: {
                initialScale = scale
            }

            onPinchUpdated: function(pinch) {
                scale = initialScale * pinch.scale
                console.log(scale)
                parent.scale = scale
            }
        }
        Text {
            text: "mumble mumble"
            font.pointSize: 10
            scale: 1.0
            color: "yellow"
            anchors.left: parent.right
        }
    }
}

which I can run using the following python code (which uses PySide6):

import sys
from pathlib import Path
from PySide6.QtQuick import QQuickView
from PySide6.QtCore import QUrl
from PySide6.QtGui import QGuiApplication


if __name__ == '__main__':

    #Set up the application window
    app = QGuiApplication(sys.argv)
    view = QQuickView()
    view.setResizeMode(QQuickView.SizeRootObjectToView)

    #Load the QML file
    qml_file = Path(__file__).parent / "test_qml_file.qml"
    view.setSource(QUrl.fromLocalFile(qml_file.resolve()))

    #Show the window
    if view.status() == QQuickView.Error:
        sys.exit(-1)
    view.show()

    #execute and cleanup
    app.exec()
    del view

Solution

  • The text scales because it is a child of the Rectangle. When any parent scales, all of the child objects will scale with it. It would be very complicated to scale large composite objects if that weren't the case.

    If you don't want the text to change, then it shouldn't be a child. You can still place the text within the Rectangle, but make it a child of the parent window or some other intermediate Item.

    Rectangle {
        id: page
        width: 1000; height: 1000
        color: "black"
    
        Rectangle {
            id: image_boundary
            color: "green"
            width: 200
            height: 100
            x: (parent.width/2)-(image_boundary.width/2)
            y: (parent.height/2)-(image_boundary.height/2)
    
            PinchArea {
                ...
            }
        }
    
        Text {
            text: "mumble mumble"
            font.pointSize: 10
            color: "yellow"
            anchors.top: image_boundary.top
            anchors.left: image_boundary.right
        }
    }