Jacob Krieg Jacob Krieg - 9 days ago 6
C++ Question

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
?

Answer

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

Comments