goocreations
goocreations

Reputation: 3066

QML - Opacity of stacked elements

I have two items that are stacked. Both items have a semi-transparent background. The circle now shows the the rounded rect below.

Stacked Opacity

Is there any way I can hide the part of the long rounded rect that overlaps with the circle? Maybe changing the parent, that the background of the circle is pulled from the ancestor higher up, and therefore ignoring the rect immediately below it?

Here is the code:

Item
{
    id: choice1
    width: 300
    height: 100

    Rectangle
    {
        id: choiceLabel1
        width: 0
        height: parent.height / 1.5
        radius: parent.height * 0.5
        color: "#88808080"
        anchors
        {
            verticalCenter: choice1.verticalCenter
            left: choice1.left
            leftMargin: choiceIcon1.width / 2
        }
        border
        {
            width: 2
            color: "red"
        }
    }
    Rectangle
    {
        id: choiceIcon1
        width: choice1.height
        height: choice1.height
        radius: width * 0.5
        color: "#88808080"
        anchors
        {
            verticalCenter: choice1.verticalCenter
            left: choice1.left
        }
        border
        {
            width: 2
            color: "red"
        }
    }
}

Upvotes: 2

Views: 1531

Answers (1)

A solution, albeit a bit hacky would be to implement your own QML MultiRectangle component, which allow to set an opacity and draw a border around a bunch of QML Rectangle

MultiRectangle.qml

import QtQuick 2.0

Item
{
    id: root
    layer.enabled: true

    property int borderWidth: 2
    property color borderColor

    Component
    {
        id: rectangle
        Rectangle{}
    }

    Component.onCompleted:{
        var temp = children.length
        for(var i=0; i<temp; i++)
            rectangle.createObject(this,
                {
                    "z":-100,
                    "anchors.centerIn": children[i],
                    "color": borderColor,
                    "width": children[i].width+borderWidth*2,
                    "height": children[i].height+borderWidth*2,
                    "radius": Math.max((children[i].height+borderWidth*2)
                                       /children[i].height*children[i].radius,
                                     (children[i].height+borderWidth*2)
                                       /children[i].height*children[i].radius)
                })

    }
}

This will dynamically create a pseudo border behind the rectangles added to a MultiRectangle item.

Example

import QtQuick 2.5
import QtQuick.Window 2.2
import QtGraphicalEffects 1.0

Window {
    id: root
    visible: true
    height: 200
    width: 400

    RadialGradient {
        anchors.fill: parent
        gradient: Gradient {
            GradientStop { position: 0.0; color: "white"}
            GradientStop { position: 0.3; color: "#444"}
            GradientStop { position: 1; color: "white"}
        }
    }

    MultiRectangle {
        anchors.centerIn: parent
        width: 300
        height: 100
        borderWidth: 2
        borderColor: "red"
        opacity: 0.5

        Rectangle {
            color: "cyan"
            anchors.verticalCenter: parent.verticalCenter
            anchors.left: parent.left
            anchors.leftMargin: parent.borderWidth
            height: parent.height - 2 * parent.borderWidth
            width: height
            radius: height / 2
        }

        Rectangle {
            color: "cyan"
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.margins: parent.borderWidth
            anchors.top: parent.top
            height: 10
            width: height
            radius: height / 2
        }

        Rectangle {
            color: "cyan"
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.horizontalCenterOffset: 30
            anchors.margins: parent.borderWidth
            anchors.top: parent.top
            height: 30
            width: height
            radius: height / 2
        }

        Rectangle {
            color: "cyan"
            anchors.verticalCenter: parent.verticalCenter
            anchors.left: parent.left
            anchors.leftMargin: 50
            height: parent.height * 0.6
            anchors.right: parent.right
            anchors.margins: parent.borderWidth
            radius: height / 2
        }
    }
}

Result

Screenshot of the qmlscene running the example

Note that since layer.enabled is set to true, clip is also set to true. Therefore, the border of child items too close to the MultiRectangle bounds will be clipped.

Upvotes: 5

Related Questions