qmlshapesopacitymask

How do I apply a RadialGradient to a Shape?


Here's what I have so far:

green arc with blue cloud

What I want, however, is to use the RadialGradient as an OpacityMask so that the outer ring of the green Shape is 100% opaque, but the straight line should taper to fully transparent in the middle of the image. None of my efforts so far have worked. When I set both the RadialGradient and the Shape to visible: false, I get nothing but the black box into which my desired image is to be drawn.

An ideal answer would also explain how one might go about troubleshooting such issues to perhaps figure it out.

import QtQuick 2.15
import QtQuick.Shapes 1.15
import QtGraphicalEffects 1.15

import QtQuick.Layouts 1.2
import QtQuick.Controls 2.15
import QtQuick.Dialogs 1.1

Rectangle {
    id: myFrame
    width: 640
    height: 640
    Rectangle {
        id: blackbox
        anchors.centerIn: parent
        anchors.fill: parent
        color: "black"
    
        layer.enabled: true
        layer.samples: 8
        RadialGradient {
            id: mask
            visible: true
            anchors.fill: parent
            gradient: Gradient {
                GradientStop { position: 0.0; color: "transparent" }
                GradientStop { position: 0.4; color: "blue" }
            }
        }
        Shape {
            id: myShape
            x: parent.width / 2
            y: parent.width / 2
            visible: true
            ShapePath {
                fillColor: "transparent"
                strokeColor: Qt.rgba(0.318, 1, 0.051, 0.9)
                strokeWidth: blackbox.height * 0.02
                capStyle: ShapePath.RoundCap
                joinStyle: ShapePath.RoundJoin
                startX: 0
                startY: 0
                PathAngleArc {
                    radiusX: 0.46 * blackbox.width 
                    radiusY: 0.46 * blackbox.height
                    startAngle: 270 
                    sweepAngle: -360 * 0.7
                    moveToStart: false
                }
            }
        }
        OpacityMask {
            anchors.fill: parent
            source: myShape
            maskSource: mask
        }
    }
}

Solution

  • This is what I came up with:

    import QtQuick 2.15
    import QtQuick.Shapes 1.15
    import QtGraphicalEffects 1.15
    
    import QtQuick.Layouts 1.2
    import QtQuick.Controls 2.15
    import QtQuick.Dialogs 1.1
    
    Rectangle {
        id: myFrame
        width: 640
        height: 640
        Rectangle {
            id: blackbox
            anchors.centerIn: parent
            anchors.fill: parent
            color: "black"
        
            layer.enabled: true
            layer.samples: 8
            RadialGradient {
                id: mask
                visible: false
                smooth: true
                anchors.fill: parent
                gradient: Gradient {
                    GradientStop { position: 0.0; color: "transparent" }
                    GradientStop { position: 0.4; color: "blue" }
                }
            }
            Shape {
                id: myShape
                anchors.fill: parent
                visible: false
                smooth: true
                ShapePath {
                    fillColor: "transparent"
                    strokeColor: Qt.rgba(0.318, 1, 0.051, 0.9)
                    strokeWidth: blackbox.height * 0.02
                    capStyle: ShapePath.RoundCap
                    joinStyle: ShapePath.RoundJoin
                    startX: myShape.width / 2
                    startY: myShape.width / 2
                    PathAngleArc {
                        centerX: myShape.width / 2
                        centerY: myShape.width / 2
                        radiusX: 0.46 * blackbox.width 
                        radiusY: 0.46 * blackbox.height
                        startAngle: 270 
                        sweepAngle: -360 * 0.7
                        moveToStart: false
                    }
                }
            }
            OpacityMask {
                anchors.fill: parent
                source: myShape
                maskSource: mask
            }
        }
    }
    

    Essentially, it sets the size of the Shape and centers ShapePath within that.

    I think the issue has something to do with the size of the Shape not actually being set (size=0x0). Everything within that is then written outside of the 'view'.