0
votes

I am currently setting up a QUI application in QML / QtQuick.

My GUI is composed of a page including a png image. This image shows arrows that should be pressed by the user to trigger some application behavior (i.e. go up / down / left / right).

The image has property fillMode: Image.PreserveAspectFit and this allows the image to scale nicely when the window is resized.

Now in order to capture the events I have setup some MouseAreas on top of the arrows. The behavior of these is great though they do not resize correctly together with the window resize. That is the whatever layout fiddling I have tried, the MouseAreas do not stay on top of the arrows (which is useless for the user obviously).

On the picture below you can see the layout as designed, with png image showing a vehicle and the arrows (they are due to move the vehicle when pressed), the MouseAreas cover the arrows correctly.

enter image description here

On the image, we can see the layout after the window was resized. The png image is correctly resized (accounting for the preserved aspect and all), but the MouseAreas are not correctly moved and resized, so they no longer cover the arrows.

enter image description here

I have tried setting up my layout with the anchor options. Then I have tried to manually compute the x, y, width height of the MouseAreas (see below for example code), but nothing works.

import QtQuick 2.7
import QtQuick.Controls 2.0

ApplicationWindow {
    visible: true
    width: 600
    height: 600
    title: qsTr("Hello World")

    Rectangle {
        id: rectangle1
        anchors.fill: parent
        color: "#222222"

        Image {
            id: backBack
            anchors.fill: parent
            fillMode: Image.PreserveAspectFit
            source: "ManualMove_allButBackgroundAndCore.png"
            smooth: true

            MouseArea {
                id: z_up
                x: 483 / backBack.implicitWidth * backBack.width
                y: 222 / backBack.implicitHeight * backBack.height
                width: 100
                height: 120
                hoverEnabled: true
                onPressed: {
                    console.log("z_up pressed width.")
                }
                onReleased: {
                    console.log("z_up released.")
                }
            }

            Rectangle {
                id: rectangle2
                x: 483 / backBack.implicitWidth * backBack.width
                y: 222 / backBack.implicitHeight * backBack.height
                width: 100
                height: 120
                color: "#ffffff"
            }
        }
    }
}

The rectangle allows to visualize the MouseArea's behavior when running the app.

---------UPDATE---------

I have added an example file to show what I mean. I would expect the white rectangle to move and resize together with the blue arrow (so the white rectangle is always on the left blue arrow).

Any idea of how I can get my layout correctly resizing?

Kind regards,

Antoine.

1
Can you provide a minimal example that runs? For example, place the backBack item into an ApplicationWindow and ensure that it reproduces your problem? That way we can run your code and play around with it. Currently there's too much missing.Mitch
Hi Mitch, I have just added a link to the example files...arennuit

1 Answers

1
votes

I think that the problem occurs because the actual position of the rendered image within the bounds of the Image item changes as its parent's size changes. You can see what I mean if you open the image up with your favourite editor and fill the background with e.g. red.

You might be able to get around this by doing the aspect stuff yourself with an Item, but I think the way you're approaching this is a bit backwards. Each "shape" in your image that should be interactive should have its own individual PNG file, and then compose a scene out of several of these. That way, you can just make the MouseArea set anchors.fill on the Image and not have to worry about where the actual rendered image is. You could make one reusable MyButton.qml that contains the Image and MouseArea combo, and then create instances of it as required. As a bonus, they'll be much more flexible, in that you can easily apply e.g. press/hover effects to them.

You'll still probably want to position these images using the same kind of scaling that you're doing now.