Qt Quick provides two shading effects:
- Dropshow, Shadow. This element produces a new color, blurred image based on the source image, and puts the new image behind the source image, giving the effect of a source image protruding from the background.
- Innershadow, inner shadow. This element produces a new color, blurred image based on the source image, and unlike DropShadow, the new image is placed inside the source image.
Effect
Here's a sample effect I've designed.
The first is DropShadow:
Figure 1 Shadow Effect
Then the inner shadow effect:
Figure 2 Inner Shadow effect
SOURCE Analysis
As shown in 1, the interface is divided into three parts.
The top is the source image.
Below the source image (that is, the middle) is a list, you can click DropShadow and Innershadow two subkeys to toggle different shadow effects. Each shadow effect corresponds to a QML document, and when you click on those subkeys, the corresponding QML document is loaded dynamically.
Shadow Sample Interface
This example interface is in fact consistent with the "graphic effect in Qt quick-color", except that I changed the ListView from the original vertical to the horizontal. The corresponding DROPSHADOWEXAMPLE.QML content is as follows:
import QtQuick 2.2
import QtQuick.Controls 1.2
Rectangle {
id: example;
signal back();
anchors.fill: parent;
Text {
id: origLabel;
x: 10;
y: 4;
font.pointSize: 20;
text: "Original Image";
}
Button {
anchors.right: parent.right;
anchors.top: parent.top;
anchors.margins: 4;
text: "Back";
onClicked: example.back();
}
Image {
id: origImage;
width: 240;
height: 240;
anchors.left: parent.left;
anchors.top: origLabel.bottom;
anchors.margins: 4;
source: "butterfly.png";
sourceSize: Qt.size(240, 240);
smooth: true;
}
Rectangle{
anchors.left: parent.left;
anchors.leftMargin: 4;
anchors.right: parent.right;
anchors.rightMargin: 4;
anchors.top: origImage.bottom;
height: 2;
border.width: 1;
border.color: "darkgray";
}
Text {
id: effectsLabel;
anchors.top: origImage.bottom;
anchors.margins: 4;
anchors.left: parent.left;
font.pointSize: 20;
font.bold: true;
text: "Shadow Effects:";
color: "blue";
}
Rectangle {
id: shadowEffects;
anchors.left: effectsLabel.right;
anchors.leftMargin: 4;
anchors.top: effectsLabel.top;
anchors.right: parent.right;
anchors.rightMargin: 4;
height: 40;
color: "gray";
ListView {
anchors.fill: parent;
clip: true;
focus: true;
orientation: ListView.Horizontal;
spacing: 20;
delegate: Text {
id: wrapper;
height: 40;
verticalAlignment: Text.AlignVCenter;
text: name;
font.pointSize: 18;
Keys.onEnterPressed: {
event.accepted = true;
effectControl.source = example;
}
Keys.onReturnPressed: {
event.accepted = true;
effectControl.source = example;
}
MouseArea {
anchors.fill: parent;
onClicked: {
wrapper.ListView.view.currentIndex = index;
effectControl.source = example;
}
}
}
highlight: Rectangle {
height: parent.height;
color: "lightblue";
}
model: shadowsModel;
}
}
Loader {
id: effectControl;
anchors.top: shadowEffects.bottom;
anchors.left: parent.left;
anchors.bottom: parent.bottom;
anchors.right: parent.right;
anchors.margins: 4;
source: "DropShadowEx.qml";
}
ListModel {
id: shadowsModel;
ListElement {
name: "DropShadow";
example: "DropShadowEx.qml";
}
ListElement {
name: "InnerShadow";
example: "InnerShadowEx.qml";
}
}
}
DROPSHAWEXAMPLE.QML will be dynamically loaded by the MAIN.QML described in "the graphical effects of Qt quick (graphical effects)".
Shadow effect
The DROPSHADOWEX.QML content of the shadow effect corresponds to the following:
import QtQuick 2.2
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.2
Rectangle {
anchors.fill: parent;
Image {
id: opImage;
x: 4;
y: 4;
width: 250;
height: 250;
source: "butterfly.png";
sourceSize: Qt.size(250, 250);
smooth: true;
visible: false;
}
DropShadow {
id: dropshadow;
anchors.fill: opImage;
source: opImage;
}
Rectangle {
anchors.left: opImage.right;
anchors.top: opImage.top;
anchors.right: parent.right;
anchors.bottom: parent.bottom;
anchors.margins: 2;
color: "lightsteelblue";
CheckBox {
id: fast;
anchors.top: parent.top;
anchors.topMargin: 4;
anchors.left: parent.left;
anchors.leftMargin: 4;
checked: false;
text: "fast";
}
CheckBox {
id: transparentBorder;
anchors.left: fast.right;
anchors.leftMargin: 8;
anchors.top: fast.top;
checked: false;
text: "transparentBorder";
}
Text {
id: colorLabel;
anchors.left: fast.left;
anchors.top: fast.bottom;
anchors.topMargin: 8;
text: "shadow color:";
}
ColorPicker {
id: shadowColor;
anchors.left: colorLabel.right;
anchors.leftMargin: 4;
anchors.top: colorLabel.top;
width: 90;
height: 28;
color: "#ff000000";
}
Text {
id: sampleLabel;
anchors.left: fast.left;
anchors.top: shadowColor.bottom;
anchors.topMargin: 8;
text: "samples:";
}
Slider {
id: sampleSlider;
anchors.left: sampleLabel.right;
anchors.leftMargin: 4;
anchors.top: sampleLabel.top;
minimumValue: 0;
maximumValue: 32;
value: 0.0;
width: 160;
height: 30;
stepSize: 1.0;
}
Text {
id: spreadLabel;
anchors.left: fast.left;
anchors.top: sampleSlider.bottom;
anchors.topMargin: 8;
text: "spread:";
}
Slider {
id: spreadSlider;
anchors.left: spreadLabel.right;
anchors.leftMargin: 4;
anchors.top: spreadLabel.top;
value: 0.5;
width: 160;
height: 30;
}
Text {
id: radiusLabel;
anchors.left: fast.left;
anchors.top: spreadSlider.bottom;
anchors.topMargin: 8;
text: "radius:";
}
Rectangle {
id: radiusArea;
anchors.left: radiusLabel.right;
anchors.leftMargin: 4;
anchors.top: radiusLabel.top;
height: 30;
width: 160;
color: "lightgray";
border.width: 1;
border.color: "darkgray";
TextInput {
anchors.fill: parent;
anchors.margins: 2;
id: radiusEdit;
font.pointSize: 18;
text: "0.0";
validator: DoubleValidator{bottom: 0;}
}
}
Text {
id: voffLabel;
anchors.left: fast.left;
anchors.top: radiusArea.bottom;
anchors.topMargin: 8;
text: "verticalOffset:";
}
Rectangle {
id: voffArea;
anchors.left: voffLabel.right;
anchors.leftMargin: 4;
anchors.top: voffLabel.top;
height: 30;
width: 160;
color: "lightgray";
border.width: 1;
border.color: "darkgray";
TextInput {
anchors.fill: parent;
anchors.margins: 2;
id: voffEdit;
font.pointSize: 18;
text: "0.0";
validator: DoubleValidator{}
}
}
Text {
id: hoffLabel;
anchors.left: fast.left;
anchors.top: voffArea.bottom;
anchors.topMargin: 8;
text: "horizontalOffset:";
}
Rectangle {
id: hoffArea;
anchors.left: hoffLabel.right;
anchors.leftMargin: 4;
anchors.top: hoffLabel.top;
height: 30;
width: 160;
color: "lightgray";
border.width: 1;
border.color: "darkgray";
TextInput {
anchors.fill: parent;
anchors.margins: 2;
id: hoffEdit;
font.pointSize: 18;
text: "0.0";
validator: DoubleValidator{}
}
}
Button {
id: applyBtn;
anchors.left: parent.left;
anchors.leftMargin: 4;
anchors.top: hoffArea.bottom;
anchors.topMargin: 12;
text: "Apply";
onClicked: {
dropshadow.color = shadowColor.color;
dropshadow.fast = fast.checked;
dropshadow.transparentBorder = transparentBorder.checked;
dropshadow.samples = sampleSlider.value;
dropshadow.radius = parseFloat(radiusEdit.text);
dropshadow.verticalOffset = voffEdit.text;
dropshadow.horizontalOffset = hoffEdit.text;
dropshadow.spread = spreadSlider.value;
}
}
}
}
The code is relatively simple and not elaborate. Let's see what the various attributes of the dropshadow element mean.
- Source,variant type, point to Source item
- HorizontalOffset with the Verticaloffset,real type, specifying the horizontal and vertical offsets of the shadow relative to the source item, which defaults to 0
- Radius,real type, sets the softness of the shadow, the higher the value, the softer the edge of the shadow appears.
- The Sample,int type that specifies how many sample points each pixel of the shadow will spawn when the shadow is generated, and the more the sample points, the better the shadow effect, but also the slower. This value can generally be set to twice times the radius.
- The Spread,real type that specifies how to harden the shadow close to the source Item edge, with a value range of 0.0--1.0, which defaults to 0.5
Not mentioned in the properties are relatively simple, want to cached, fast, transparentborder, etc., the previous article also mentioned.
Inner Shadow
The INNERSHADOWEX.QML content corresponding to the inner shadow effect is as follows:
import QtQuick 2.2
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.2
Rectangle {
anchors.fill: parent;
Image {
id: opImage;
x: 4;
y: 4;
width: 250;
height: 250;
source: "butterfly.png";
sourceSize: Qt.size(250, 250);
smooth: true;
visible: false;
}
InnerShadow {
id: innershadow;
anchors.fill: opImage;
source: opImage;
}
Rectangle {
anchors.left: opImage.right;
anchors.top: opImage.top;
anchors.right: parent.right;
anchors.bottom: parent.bottom;
anchors.margins: 2;
color: "lightsteelblue";
CheckBox {
id: fast;
anchors.top: parent.top;
anchors.topMargin: 4;
anchors.left: parent.left;
anchors.leftMargin: 4;
checked: false;
text: "fast";
}
Text {
id: colorLabel;
anchors.left: fast.left;
anchors.top: fast.bottom;
anchors.topMargin: 8;
text: "shadow color:";
}
ColorPicker {
id: shadowColor;
anchors.left: colorLabel.right;
anchors.leftMargin: 4;
anchors.top: colorLabel.top;
width: 90;
height: 28;
color: "#ff000000";
}
Text {
id: sampleLabel;
anchors.left: fast.left;
anchors.top: shadowColor.bottom;
anchors.topMargin: 8;
text: "samples:";
}
Slider {
id: sampleSlider;
anchors.left: sampleLabel.right;
anchors.leftMargin: 4;
anchors.top: sampleLabel.top;
minimumValue: 0;
maximumValue: 32;
value: 0.0;
width: 160;
height: 30;
stepSize: 1.0;
}
Text {
id: spreadLabel;
anchors.left: fast.left;
anchors.top: sampleSlider.bottom;
anchors.topMargin: 8;
text: "spread:";
}
Slider {
id: spreadSlider;
anchors.left: spreadLabel.right;
anchors.leftMargin: 4;
anchors.top: spreadLabel.top;
value: 0.5;
width: 160;
height: 30;
}
Text {
id: radiusLabel;
anchors.left: fast.left;
anchors.top: spreadSlider.bottom;
anchors.topMargin: 8;
text: "radius:";
}
Rectangle {
id: radiusArea;
anchors.left: radiusLabel.right;
anchors.leftMargin: 4;
anchors.top: radiusLabel.top;
height: 30;
width: 160;
color: "lightgray";
border.width: 1;
border.color: "darkgray";
TextInput {
anchors.fill: parent;
anchors.margins: 2;
id: radiusEdit;
font.pointSize: 18;
text: "0.0";
validator: DoubleValidator{bottom: 0;}
}
}
Text {
id: voffLabel;
anchors.left: fast.left;
anchors.top: radiusArea.bottom;
anchors.topMargin: 8;
text: "verticalOffset:";
}
Rectangle {
id: voffArea;
anchors.left: voffLabel.right;
anchors.leftMargin: 4;
anchors.top: voffLabel.top;
height: 30;
width: 160;
color: "lightgray";
border.width: 1;
border.color: "darkgray";
TextInput {
anchors.fill: parent;
anchors.margins: 2;
id: voffEdit;
font.pointSize: 18;
text: "0.0";
validator: DoubleValidator{}
}
}
Text {
id: hoffLabel;
anchors.left: fast.left;
anchors.top: voffArea.bottom;
anchors.topMargin: 8;
text: "verticalOffset:";
}
Rectangle {
id: hoffArea;
anchors.left: hoffLabel.right;
anchors.leftMargin: 4;
anchors.top: hoffLabel.top;
height: 30;
width: 160;
color: "lightgray";
border.width: 1;
border.color: "darkgray";
TextInput {
anchors.fill: parent;
anchors.margins: 2;
id: hoffEdit;
font.pointSize: 18;
text: "0.0";
validator: DoubleValidator{}
}
}
Button {
id: applyBtn;
anchors.left: parent.left;
anchors.leftMargin: 4;
anchors.top: hoffArea.bottom;
anchors.topMargin: 12;
text: "Apply";
onClicked: {
innershadow.color = shadowColor.color;
innershadow.fast = fast.checked;
innershadow.samples = sampleSlider.value;
innershadow.radius = parseFloat(radiusEdit.text);
innershadow.verticalOffset = voffEdit.text;
innershadow.horizontalOffset = hoffEdit.text;
innershadow.spread = spreadSlider.value;
}
}
}
}
The source code is relatively simple, do not say.
Innershadow less than DropShadow a Transparentborder attribute, the other basic consistent, steal a lazy, also do not say.
Look Back:
- The graphic effect of Qt quick-gradient (Gradient)
- The graphic effect in Qt quick-color
- The graphic effect of Qt quick-blend (blend)
- Graphical effects in Qt quick (graphical effects)
- Qt Quick Column
The graphics effect in Qt quick: Shadows (drop Shadow)