Search code examples
qtqmldropshadow

QML Text Drop Shadow


Is there a proper way of adding outer shadow to a text object in QML? I've tried to use the DropShadow but it fills the whole text field with black.

Text {
    id: textId
    font.pixelSize: 36
    font.letterSpacing: 0.9
    color: "red"
    text: "Hello World"

    DropShadow {
        anchors.fill: parent
        verticalOffset: 2
        color: "#80000000"
        radius: 1
        samples: 3
    }
}

I've also tried to replace anchors.fill with source and set the text id. Also with DropShadow outside of the Text object. No shadow is present.

My goal is to get the equivalent of the css style

text-shadow: 0 2px 4px

Solution

  • The easiest way would be to use item layers:

    import QtQuick 2.9
    import QtQuick.Window 2.3
    import QtGraphicalEffects 1.0
    
    Window {
        id: window
        width: 800
        height: 600
        visible: true
    
        Text {
            id: textId
            font.pixelSize: 36
            font.letterSpacing: 0.9
            color: "red"
            text: "Hello World"
    
            layer.enabled: true
            layer.effect: DropShadow {
                verticalOffset: 2
                color: "#80000000"
                radius: 1
                samples: 3
            }
        }
    }
    

    You can also do it like it's done in the DropShadow docs, where the DropShadow is a sibling item:

    import QtQuick 2.9
    import QtQuick.Window 2.3
    import QtGraphicalEffects 1.0
    
    Window {
        id: window
        width: 800
        height: 600
        visible: true
    
        Text {
            id: textId
            font.pixelSize: 36
            font.letterSpacing: 0.9
            color: "red"
            text: "Hello World"
        }
    
        DropShadow {
            anchors.fill: textId
            source: textId
            verticalOffset: 2
            color: "#80000000"
            radius: 1
            samples: 3
        }
    }
    

    You're missing the source assignment in your case, but you'll also get errors about recursive rendering if you try to have the shadow as a child of the Text:

    ShaderEffectSource: 'recursive' must be set to true when rendering recursively.