How to change the position when the parent is resized?

Viewed 402

How do I properly change the x, y of an object so that it changes its position when the parent is resized? There is, I will introduce that if I drag the rectangle to the middle, then when the window is resized, it should remain in the middle. (middle for example only, rectangle can be moved freely)

Example

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.3

Window {
    visible: true
    width: 640
    height: 480

onWidthChanged: {
            block.x -= block.previousWidth - width
            block.previousWidth = width
        }

onHeightChanged: {
            block.y -= block.previousHeight - height
            block.previousHeight = height
        }

    Rectangle {
        id: block
        color: "red"
        width: 50
        height:50
        x: 100
        y: 50

       property int previousWidth: 0
       property int previousHeight:0

       Component.onCompleted: { 
          previousWidth = parent.width
          previousHeight  = parent.height
}

        MouseArea {
            anchors.fill: parent
            drag.target: block
        }
    }
}
2 Answers

I must admit, at first I was not impressed by the question. However, when I thought about it, it represents a very interesting and valid use case. So I would be happy to provide a solution.

Solution

I would approach the problem like this:

  1. Make the frame a child of the background image.
  2. Instead of manually calculating the coordinates, use Item.scale to scale the image, effectively preserving the relative position of the frame with regard to the image.

Example

Here is an example I have prepared for you to demonstrate how the proposed solution could be implemented:

import QtQuick 2.15
import QtQuick.Window 2.15

Window {
    visible: true
    width: 640
    height: 480

    Image {
        anchors.centerIn: parent
        source: "alphabet.png"
        scale: parent.width/sourceSize.width

        Rectangle {
            id: frame

            width: parent.width/7
            height: parent.height/4
            border.color: "black"
            color: "transparent"
            antialiasing: true

            MouseArea {
                anchors.fill: parent
                drag.target: parent
            }
        }
    }
}

Result

The example produces the following result:

Original window

Original window

Resized window

Resized window

The frame is moved

Moved frame

The window is resized again

Moved frame and resized window

As I said in my comment, the best solution is anchoring, for example:

Window {
    id: root
    width: 600
    height: 400
    title: qsTr("Parent window")
    visible: true
    flags: Qt.WindowStaysOnTopHint

    Grid {
        anchors.fill: parent
        Repeater {
            model:  16
            Rectangle {
                width: root.width / 4
                height: root.height / 4
                color: Qt.rgba(Math.random(),Math.random(),Math.random(),1)
            }
        }
    }
    Rectangle {
        border {
            width: 5
            color: "black"
        }
        color: "transparent"
        width: root.width / 4
        height: root.height / 4
        anchors.bottom: parent.bottom
        anchors.left: parent.left
        anchors.leftMargin: root.width / 4
        anchors.bottomMargin: root.height / 4
    }
}
Related