2
votes

I was developing a small application using QML, and i need a small drop shadow on the text component, to make it more readable, but when I add the DropShadow to the Label in the Column, it throws an error:

"QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column. Column will not function."

But the text should overlap each other, here is my sample code:

import QtQuick 2.2
import QtGraphicalEffects 1.0

Item {
    width: 100
    height: 200
    Column {
        Label {
            id: label1
            anchors.horizontalCenter: parent.horizontalCenter
            text: "First label"
        }
        DropShadow {
            anchors.fill: label1
            radius: 16
            samples: 32
            color: "#b0000000"
            source: label1
        }
        Label {
            id: label2
            anchors.horizontalCenter: parent.horizontalCenter
            text: "Second label"
        }
        DropShadow {
            anchors.fill: label2
            radius: 16
            samples: 32
            color: "#b0000000"
            source: label2
        }
    }
}

Did I make some mistakes? Or can't I use DropShadow inside a Column? Should I use Item instead of Column? Thank you in advance!

2

2 Answers

2
votes

You have several issues here.

The first is already explained by the error message you receive; you can't use vertical anchors in a column, and anchors.fill: parent implies both horizontal and vertical anchors. You can use the width and height properties instead:

import QtQuick 2.2
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.0
import QtQuick.Window 2.0

Window {
    width: 100
    height: 200
    visible: true

    Column {
        Label {
            id: label1
            anchors.horizontalCenter: parent.horizontalCenter
            text: "First label"
        }
        DropShadow {
            width: label1.width
            height: label1.height
            radius: 16
            samples: 32
            color: "#b0000000"
            source: label1
        }
        Label {
            id: label2
            anchors.horizontalCenter: parent.horizontalCenter
            text: "Second label"
        }
        DropShadow {
            width: label2.width
            height: label2.height
            radius: 16
            samples: 32
            color: "#b0000000"
            source: label2
        }
    }
}

However, this introduces new problems:

enter image description here

You can see that there are duplicates of the labels. This is explained in the documentation of DropShadow:

Generates a colorized and blurred shadow image of the source and places it behind the original, giving the impression that source item is raised from the background.

So, you can set visible: false on label1 and label2.

The next issue is that the DropShadow will be restricted to the bounding rectangle of the Label. With the examples in the documentation for DropShadow, this is not a problem, because the bounds of the content is much smaller than the bounds of the actual item:

enter image description here

Since there is not much distance between the pixels making up the text and the boundary of the Label, you have to account for that yourself.

I doubt that this is the most elegant solution, but I'm not aware of a better one:

import QtQuick 2.4
import QtQuick.Window 2.0
import QtQuick.Controls 1.0
import QtGraphicalEffects 1.0

Window {
    id: win
    width: 150
    height: 150
    visible: true

    Item {
        width: 100
        height: 200
        Column {
            Item {
                width: label1.implicitWidth + 20
                height: label1.implicitHeight + 20
                anchors.horizontalCenter: parent.horizontalCenter
                visible: false

                Label {
                    id: label1
                    text: "First label"
                    anchors.centerIn: parent
                }
            }
            DropShadow {
                width: label1.width
                height: label1.height
                radius: 4
                samples: 8
                color: "#b0000000"
                source: label1
            }
            Item {
                width: label2.implicitWidth + 20
                height: label2.implicitHeight + 20
                anchors.horizontalCenter: parent.horizontalCenter
                visible: false

                Label {
                    id: label2
                    text: "Second label"
                    anchors.centerIn: parent
                }
            }
            DropShadow {
                width: label2.width
                height: label2.height
                radius: 4
                samples: 8
                color: "#b0000000"
                source: label2
            }
        }
    }
}

enter image description here

Note that I also reduced the radius of the shadow to make it more noticeable.

0
votes

The way you have it right now, the drop shadow labels would occupy its own columns, therefore you cannot use the anchors.fill keyword.

Try putting the DropShadow inside the Label:

Label {
        id: label1
        anchors.horizontalCenter: parent.horizontalCenter
        text: "First label"
        DropShadow {
            anchors.fill: label1
            horizontalOffset: 1
            verticalOffset: 1
            radius: 1
            samples: 3
            color: "Red"
            source: label1
        }
   }

better yet, put all this code in a separate file: DropShadowText.qml, and us it as a unique component:

DropShadowText{

}

Good luck!