Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QML Inner Shadow effect

I want to create a rectangle with inner shadow in QML, something similar with what Photoshop does:

enter image description here

QML has InnerShadow but I'm unable to achieve this effect. The closest I got was this

import QtQuick 2.0
import QtGraphicalEffects 1.0

Item {
    id: root
    width: 300
    height: 300

    Rectangle {
        id: myRectangle
        anchors.centerIn: parent
        width: 100
        height: 100
        color: "grey"
    }

    InnerShadow {
        anchors.fill: root
        cached: true
        horizontalOffset: 0
        verticalOffset: 0
        radius: 16
        samples: 32
        color: "#b0000000"
        smooth: true
        source: root
    }
}

which is an idea I got from this post. However this example only works if root has a significantly bigger size than myRectangle and I don't want that. I need e.g. a 200x10 square in which shadow is uniformly spread across the edges of the rectangle. I tried all kinds of values for the InnerShadow properties but I couldn't get even close to the effect I want.

Can this be achieved using QML?

like image 413
Jacob Krieg Avatar asked Jul 22 '26 08:07

Jacob Krieg


1 Answers

The "correct" approach - quotation marks needed - to use the effect should be this one:

import QtQuick 2.0
import QtGraphicalEffects 1.0

Item {
   id: root
   width: 300
   height: 300

   Item {
       id: src
       anchors.fill: parent

       Rectangle {
           id: myRectangle
           anchors.centerIn: parent
           width: 100
           height: 100
           color: "grey"
       }
   }

   InnerShadow {
       anchors.fill: src
       cached: true
       horizontalOffset: 0
       verticalOffset: 0
       radius: 16
       samples: 32
       color: "#b0000000"
       smooth: true
       source: src
   }
}

As you can see it is slightly different from the propose solution in the other question. Using this code you still need to left 2 pixels, to have the effect, which results in a white border (or whatever is the background color). The issue can be easily solved by changing the root to be a Rectangle.

Final example solution follows. Clearly you can extract the root component (and related children) and place it in a Component or a different .qml file for later usage.

import QtQuick 2.4
import QtQuick.Window 2.2
import QtGraphicalEffects 1.0

Window {
    width: 200
    height: 20
    visible: true

    Rectangle {     // was Item
        id: root
        anchors.fill: parent
        color: "grey"


        Item {
            id: src
            anchors.fill: parent

            Rectangle {
                id: myRectangle
                anchors.centerIn: parent
                width: root.width - 2
                height: root.height - 2
                color: "lightgrey"
            }
        }

        InnerShadow {
            anchors.fill: src
            cached: true
            horizontalOffset: 0
            verticalOffset: 0
            radius: 16
            samples: 32
            color: "#b0000000"
            smooth: true
            source: src
        }
    }
}

The resulting window for the final code example:

enter image description here

like image 162
BaCaRoZzo Avatar answered Jul 24 '26 00:07

BaCaRoZzo