0

I have a basic background from a blue image with a transparent background (PNG), how can I make a different background from the image after the arrow?

I tried the option using a mask, but it cuts the picture either in width or in height, this does not work

blue background:

blue background

it should be:

it should be

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Window 2.15
import QtQuick.Controls.Styles 1.4
import QtQuick.Extras 1.4
import QtQuick.Extras.Private 1.0
import QtGraphicalEffects 1.0
Window {
width: 1280
height: 480
visible: true
title: qsTr("Hello World")
color: "#000"


CircularGauge {
    id:gauge
    property bool accelerating
    width: 377
    height: 377
    anchors.top: parent.top
    anchors.horizontalCenter: parent.horizontalCenter
    anchors.topMargin: 101
    maximumValue:8
    value:  accelerating ? maximumValue : 0

    Component.onCompleted: forceActiveFocus()
    Behavior on value { NumberAnimation { duration: 1500 }}
    Keys.onSpacePressed: accelerating = true
    Keys.onReleased: {
        if (event.key === Qt.Key_Space) {
            accelerating = false;
            event.accepted = true;
        }
    } 
    style: CircularGaugeStyle { 
        labelStepSize: 1
        labelInset: outerRadius / 6
        minimumValueAngle: -110
        maximumValueAngle: 110 
        background: Rectangle {
            id: rectangle
            implicitHeight: gauge.height
            implicitWidth: gauge.width
            color:"Transparent"
            anchors.centerIn: parent
            radius: 360

            Image {
                width: 417
                height: 287
                anchors.top: parent.top
                source: "Blue_bg.png"
                anchors.topMargin:  -23
                anchors.horizontalCenter: parent.horizontalCenter
                asynchronous: true
                sourceSize {
                }
            }


        }

        

        foreground: Item {
            Text {
                id: speedLabel
                anchors.centerIn: parent
                anchors.verticalCenterOffset: -20
                text: "126"
                font.pixelSize:76
                color: "white"
                antialiasing: true
            }
        }

        tickmarkLabel:  Text {
            font.italic: true
            font.bold: true
            text: styleData.value
            font.pixelSize: 30
            color: styleData.value <= gauge.value ? "white" : "#ffffff"
            antialiasing: true
        }

    }

}

}

How can I achieve this effect?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • With simple QML cases we can just try to use z (level) property to either raise or lower the item we want to overlap somehow from top or the other way. I am not giving this as an answer because not 100% sure that that is what works for you. https://doc.qt.io/qt-5/qml-qtquick-item.html#z-prop – Alexander V Aug 27 '21 at 18:55
  • Thanks for the answer, I tried it this way, not my option) – Антон Антонов Aug 30 '21 at 08:15

1 Answers1

0

You can use a Canvas to draw an arc (see Draw an arc/circle sector in QML?). If you combine this with an OpacityMask (see QML Circular Gauge) you can mask the blue "background" (it's more like a foreground in the given example) to make that cool speedometer :-)

import QtQuick 2.12
import QtQuick.Window 2.12
import QtGraphicalEffects 1.0

Window {
    width: 640
    height: 480
    visible: true

    Image {
        id: img
        source: "blue.png"
        visible: false
    }

    Canvas {
        id: mask
        anchors.fill: img

        property double angle: 45
        onPaint: {
            var ctx = getContext("2d");
            var centerX = width / 2;
            var centerY = height / 2;

            ctx.beginPath();
            ctx.fillStyle = "black";
            ctx.moveTo(centerX, centerY);
            ctx.arc(centerX, centerY, width / 4, (Math.PI) * (1 + angle / 180), 0, false);
            ctx.lineTo(centerX, centerY);
            ctx.fill();
        }
    }

    OpacityMask {
        anchors.fill: img
        source: img
        maskSource: mask
    }
}
Amfasis
  • 3,932
  • 2
  • 18
  • 27
  • Thanks for the help. Working option yes. But, if everything happens on a transparent background, then there is a problem =) – Антон Антонов Aug 30 '21 at 08:14
  • I don't understand, you can still have blue.png be partially transparent, applying the OpacityMask will mean it will be transparent in a bigger region, so the background can also be transparent. – Amfasis Aug 30 '21 at 08:37