Search code examples
c++qtc++17cross-platformdesktop-application

how can i generate a box-shadow rather than a drop-shadow? Qt/c++ 6.4.1


i'm trying to create a box-shadow effect for my customs widget, but i can't find a way to do that!.

Using QGraphicsDropShadowEffect class generate a shadow that is the copy of the shape of the widget itself and put that copy behind the widget. So, when i set a opacity of 50% to my widget, the shadow is seeing trought the widget, and what i want to achive is something more like the box-shadow effect pressent in the web CSS styles, for example:

css generated:

https://i.ibb.co/mG1XXG2/box-shadow-qt-ask1.png

QGraphicsDropShadowEffect generated:

https://i.ibb.co/y680RKx/box-shadow-qt-ask2.png

As you can see, both of my elements has a shadow, and a opacity of 50%, the css generate haven't a shadow visible trought the semi transparent div element, but the shadow generated by QGraphicsDropShadowEffect can be seeing thounght the semi transparent widget, there's some way to achive to create a custom shadow that behave like css box-shadow but on my Qt/c++ widget?

Sorry if i'm not clear enoungh, i'm not an expert speaking english. Thank you for your patience.


Solution

  • A cheat would be to group your object + drop shadow as a single item. Whilst making that entire object invisible, you copy the entire item with a dummy OpacityMask. Then, you apply the opacity to the OpacityMask.

    For example:

    import QtQuick
    import QtQuick.Controls
    import Qt5Compat.GraphicalEffects
    
    Page {
        background: Rectangle { color: "#ccc" }
        Frame {
            id: butterflyWithBoxShadow
            anchors.centerIn: parent
            visible: false
            padding: 15
            background: Item {
                Rectangle {
                    anchors.fill: parent
                    anchors.leftMargin: butterflyWithBoxShadow.padding * 2
                    anchors.topMargin: butterflyWithBoxShadow.padding * 2
                    color: "grey"
                    opacity: 0.5
                }
            }
            Frame {
                id: frame
                padding: 1
                background: Rectangle {
                    border.color: "blue"
                    border.width: 1
                    color: "#ffe"
                }            
                Image {
                    id: butterfly
                    fillMode: Image.PreserveAspectFit
                    source: "https://www.arcgis.com/sharing/rest/content/items/185841a46dd1440d87e6fbf464af7849/data"
                    smooth: true
                }
            }
        }
        OpacityMask {
            anchors.fill: butterflyWithBoxShadow
            source: butterflyWithBoxShadow
            invert: true
            opacity: slider.value
        }
        Frame {
            anchors.horizontalCenter: parent.horizontalCenter
            y: parent.height * 8 / 10
            background: Rectangle { }
            Slider {
                id: slider
                from: 0
                to: 1
                value: 0.8
            }
        }
    }
    

    You can Try it Online!