Qt Quick里的图形效果:阴影(Drop Shadow)
Qt Quick提供了两种阴影效果:
- DropShow,阴影。这个元素会根据源图像,产生一个彩色的、模糊的新图像,把这个新图像放在源图像后面,给人一种源图像从背景上凸出来的效果。
- InnerShadow,内阴影。这个元素会根据源图像,产生一个彩色的、模糊的新图像,与 DropShadow不同的是,新图像会放在源图像里面。
效果
下面是我设计的示例效果。
首先是 DropShadow :
图1 阴影效果
然后是内阴影效果:
图2 内阴影效果
源码分析
如图1所示,界面被分为三部分。
最上面的是源图像。
源图像下面(即中间)是一个列表,你可以点击 DropShadow 和 InnerShadow 两个子项,切换不同的阴影效果。每种阴影效果都对应一个 qml 文档,当你点击这些子项时,对应的 qml 文档动态加载。
阴影示例界面
这个示例界面框架其实与“Qt Quick里的图形效果——颜色(Color)”是一致的,只是我把 ListView 从原来的竖向改为了横向。对应的 DropShadowExample.qml 内容如下:
- 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 会被“Qt Quick里的图形效果(Graphical Effects)”里介绍过的 main.qml 动态加载。
阴影效果
阴影效果对应的 DropShadowEx.qml 内容如下:
- 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;
- }
- }
- }
- }
代码比较简单,不细说了。我们看看 DropShadow 元素的各个属性都什么含义吧。
- source,variant类型,指向源Item
- horizontalOffset 与verticalOffset,real类型,指定阴影相对于源Item的水平和垂直偏移量,默认为 0
- radius,real类型,设置阴影的柔和程度,值越大,阴影的边缘就会显得越柔和
- sample,int类型,指定生成阴影时阴影的每个像素由多少个采样点产生,采样点越多阴影效果越好,不过也越慢。一般可以把这个值设置为 radius的2倍。
- spread,real类型,指定如何强化阴影接近源 Item 边缘的部分,取值范围为 0.0 -- 1.0 ,默认为 0.5
未提及的属性都比较简单,想 cached 、 fast 、 transparentBorder 等,之前的文章也提到过。
内阴影
内阴影效果对应的 InnerShadowEx.qml 内容如下:
- 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;
- }
- }
- }
- }
源码比较简单,不说了。
InnerShadow 比 DropShadow 少了一个 transparentBorder 属性,其他基本一致,偷个懒,也不说了。
回顾一下:
Qt Quick里的图形效果:阴影(Drop Shadow)的更多相关文章
- Qt Quick实现的疯狂算数游戏
使用 Qt Quick 写了个小游戏:疯狂算数.支持 Windows 和 Android 两个平台. 游戏简单,但牵涉到下面你的 Qt Quick 主题: 自己实现一个按钮 自适应分辨率 国际化 QM ...
- Qt Quick实现的涂鸦程序
之前一直以为 Qt Quick 里 Canvas 才干够自绘.后来发觉不是,原来还有好几种方式都能够画图! 能够使用原始的 OpenGL(Qt Quick 使用 OpenGL 渲染).能够构造QSGN ...
- Qt Quick之StackView具体解释(1)
Qt Quick中有个StackView.我在<Qt Quick核心编程>一书中没有讲到.近期有人问起,趁机学习了一下,把它的基本使用方法记录下来. 我准备分两次来讲.第一次讲主要的使用方 ...
- Qt Quick综合实例之文件查看器
假设你基于Qt SDK 5.3.1来创建一个Qt Quick App项目,项目模板为你准备的main.qml文档的根元素是ApplicationWindow或Window.这次我们就以Applicat ...
- 《Qt Quick 4小时入门》学习笔记
http://edu.csdn.net/course/detail/1042/14804?auto_start=1 Qt Quick 4小时入门 第五章:Qt Quick里的信号与槽 QML中 ...
- Qt5官方demo分析集11——Qt Quick Particles Examples - Affectors
在这个系列中的所有文章都可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集10--Qt ...
- Qt Widgets、QML、Qt Quick的区别
Qt Widgets.QML.Qt Quick的区别 简述 看了之前关于 QML 的一些介绍,很多人难免会有一些疑惑: Q1:QML 和 Qt Quick 之间有什么区别? Q2:QtQuick 1. ...
- 浏览器上的Qt Quick
你想不想在浏览器上运行你的Qt Quick程序呢?在Qt 5.12之前,唯一的方法是使用Qt WebGL Streaming技术把界面镜像到浏览器上.但该方法有不少缺陷,下文会说.前不久随着Qt 5. ...
- Qt on Android: Qt Quick 之 Hello World 图文具体解释
在上一篇文章,<Qt on Android:QML 语言基础>中,我们介绍了 QML 语言的语法,在最后我们遗留了一些问题没有展开,这篇呢,我们就正式開始撰写 Qt Quick 程序,而那 ...
随机推荐
- BOS物流管理系统-第一天
BOS物流管理系统-第一天-系统分析.环境搭建.前端框架 BoBo老师 整体项目内容目标: 对项目概述的一些理解 亮点技术的学习 注意学习方式:优先完成当天代码. 其他内容. 最终: 学到新的技术,会 ...
- jq获取上级、同级、下级元素
下面介绍JQUERY的父,子,兄弟节点查找方法 jQuery.parent(expr) 找父亲节点,可以传入expr进行过滤,比如$("span").parent()或者$(&qu ...
- 字符串匹配—KMP 扩展KMP Manacher
kuangbin字符串专题传送门--http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70325#overview 算法模板: KMP: ; ...
- POJ 2054 Color a Tree#贪心(难,好题)
题目链接 代码借鉴此博:http://www.cnblogs.com/vongang/archive/2011/08/19/2146070.html 其中关于max{c[fa]/t[fa]}贪心原则, ...
- 【同行说】Android图片处理技术资料汇总(一)
对于Android开发的童鞋们来说,图片处理时或多或少都会遇到令人头疼和不满意的问题,今天小编收集了5篇Android图片处理的干货文章,一起来看看吧! 一.Android 高清加载巨图方案 拒绝压缩 ...
- 转Rollback后undo到底做了些什么?
转自:http://biancheng.dnbcw.info/oracle/309191.html Rollback后undo到底做了些什么? 从概念上讲,undo正好与redo相对.当你对数据执行修 ...
- MVC3+EF4.1学习系列(六)-----导航属性数据更新的处理
通过上一篇的学习 我们已经知道怎么查询关系 这篇就来说说怎么导航属性数据更新时的处理 以及EF又会为我们生成哪些SQL~ 老规矩 先看下今天的图 添加和修改页面基本就是这样 这节的内容相对简单~~ 主 ...
- Android应用测试性能的工具Emmagee,导出文件格式问题分析
原文引用自:http://www.open-open.com/lib/view/open1367026451078.html Emmagee是监控指定被测应用在使用过程中占用机器的CPU.内存.流量资 ...
- ubuntu下的ssh工具gstm
(转自:http://www.nenew.net/ubuntu-ssh-gstm.html) 首先安装: sudo apt-get install gstm 就可以安装,当然你也可以到http://s ...
- 588. [NOIP1999] 拦截导弹
588. [NOIP1999] 拦截导弹 ★ 输入文件:missile.in 输出文件:missile.out 简单对比 时间限制:1 s 内存限制:128 MB 题目描述 某国为了防御敌国的导 ...