16

How can i draw a drop shadow for a Rectangle visual item on QtQuick 2.0?
I like to draw a drop shadow for my main window (I have a transparent and no-decorated window)

BaCaRoZzo
  • 7,502
  • 6
  • 51
  • 82
S.M.Mousavi
  • 5,013
  • 7
  • 44
  • 59

4 Answers4

16

As a workaround for the clipped shadow issue, you can put your Rectangle in an Item, with additionnal margin to take blur radius in account, and apply shadow on that container:

import QtQuick 2.0
import QtGraphicalEffects 1.0

Item {
    width: 320
    height: 240

    Item {
        id: container
        anchors.centerIn: parent
        width:  rect.width  + (2 * rectShadow.radius)
        height: rect.height + (2 * rectShadow.radius)
        visible: false

        Rectangle {
            id: rect
            width: 100
            height: 50
            color: "orange"
            radius: 7
            antialiasing: true
            border {
                width: 2
                color: "red"
            }
            anchors.centerIn: parent
        }
    }

    DropShadow {
        id: rectShadow
        anchors.fill: source
        cached: true
        horizontalOffset: 3
        verticalOffset: 3
        radius: 8.0
        samples: 16
        color: "#80000000"
        smooth: true
        source: container
    }
}
BaCaRoZzo
  • 7,502
  • 6
  • 51
  • 82
TheBootroo
  • 7,408
  • 2
  • 31
  • 43
  • 2
    I forgot it, but you should specify `visible: false` on the Item container, because the DropShadow effect duplicates the source item on its own, so it will avoid strange rendering issues. – TheBootroo Mar 27 '13 at 11:02
  • In my case Qt 5.15.2 this caused the internals of container not receive any touch/mouse events on iOS. – Vega4 May 17 '21 at 07:08
9

Just use DropShadow from the QtGraphicalEffects module.

A complete, working example:

import QtQuick 2.0
import QtGraphicalEffects 1.0

Rectangle {
    width: 640
    height: 480
    color: "blue"

    Rectangle {
        id: rect
        anchors.centerIn: parent
        width: 100
        height: 100
        color: "red"
    }

    DropShadow {
        anchors.fill: rect
        cached: true
        horizontalOffset: 3
        verticalOffset: 3
        radius: 8.0
        samples: 16
        color: "#80000000"
        source: rect
    }
}

Note that you will see a number of warnings like this:

file:///opt/Qt5.0.1/5.0.1/gcc_64/qml/QtGraphicalEffects/DropShadow.qml:391:5: QML SourceProxy: Binding loop detected for property "output" file:///opt/Qt5.0.1/5.0.1/gcc_64/qml/QtGraphicalEffects/private/GaussianDirectionalBlur.qml:66:5: QML SourceProxy: Binding loop detected for property "output" file:///opt/Qt5.0.1/5.0.1/gcc_64/qml/QtGraphicalEffects/private/GaussianDirectionalBlur.qml:61:5: QML SourceProxy: Binding loop detected for property "output" file:///opt/Qt5.0.1/5.0.1/gcc_64/qml/QtGraphicalEffects/private/GaussianDirectionalBlur.qml:66:5: QML SourceProxy: Binding loop detected for property "output" file:///opt/Qt5.0.1/5.0.1/gcc_64/qml/QtGraphicalEffects/private/GaussianDirectionalBlur.qml:61:5: QML SourceProxy: Binding loop detected for property "output" file:///opt/Qt5.0.1/5.0.1/gcc_64/qml/QtGraphicalEffects/private/GaussianGlow.qml:53:5: QML SourceProxy: Binding loop detected for property "output"

Those warnings are QTBUG-28521, which has been fixed in Qt 5.0.2 (which at the time of this writing has not yet been released). Fortunately, there's no actual problem, aside from the annoying console output.

cgmb
  • 4,284
  • 3
  • 33
  • 60
5

Interesting question... I've been searching for a better way to do this. This is my quick and dirty way of accomplishing a drop shadow effect for a QML Rectangle for the time being.

Rectangle{
    width: 500
    height: 500
    color: "dark grey"


    Rectangle {
        id: backgroundRect
        width: 200
        height: 150
        radius: 5
        anchors.centerIn: parent
        color: "red"

        Rectangle {
            id: dropShadowRect
            property real offset: Math.min(parent.width*0.025, parent.height*0.025)
            color: "purple"
            width: parent.width
            height: parent.height
            z: -1
            opacity: 0.75
            radius: backgroundRect.radius + 2
            anchors.left: parent.left
            anchors.leftMargin: -offset
            anchors.top: parent.top
            anchors.topMargin: offset
        }
    }
}
stackunderflow
  • 10,122
  • 4
  • 20
  • 29
0

I tried the code above and it in fact adds a shadow, although in my case simply adding another rectangle with a bit on an offset gave me an effect that I liked more.

Rectangle{

    id: rec_Shadow
    height:rect_withShadow.height
    width: rect_withShadow.width
    border.color: "#B3B3B3"
    color: "#C5C5C5"

    anchors{
            verticalCenter: rect_withShadow.verticalCenter
            horizontalCenter:  rect_withShadow.horizontalCenter
            horizontalCenterOffset: 5
            verticalCenterOffset: 5
        }
    radius: rect_withShadow.radius
}

Next you add the Rectangle on which you want the shadow, and you call it rect_withShadow