Qt Quick提供了两种阴影效果:

  • DropShow,阴影。这个元素会根据源图像,产生一个彩色的、模糊的新图像,把这个新图像放在源图像后面,给人一种源图像从背景上凸出来的效果。
  • InnerShadow,内阴影。这个元素会根据源图像,产生一个彩色的、模糊的新图像,与 DropShadow不同的是,新图像会放在源图像里面。

效果

下面是我设计的示例效果。

首先是 DropShadow :

图1 阴影效果

然后是内阴影效果:

图2 内阴影效果

源码分析

如图1所示,界面被分为三部分。

最上面的是源图像。

源图像下面(即中间)是一个列表,你可以点击 DropShadow 和 InnerShadow 两个子项,切换不同的阴影效果。每种阴影效果都对应一个 qml 文档,当你点击这些子项时,对应的 qml 文档动态加载。

阴影示例界面

这个示例界面框架其实与“Qt Quick里的图形效果——颜色(Color)”是一致的,只是我把 ListView 从原来的竖向改为了横向。对应的 DropShadowExample.qml 内容如下:

  1. import QtQuick 2.2
  2. import QtQuick.Controls 1.2
  3. Rectangle {
  4. id: example;
  5. signal back();
  6. anchors.fill: parent;
  7. Text {
  8. id: origLabel;
  9. x: 10;
  10. y: 4;
  11. font.pointSize: 20;
  12. text: "Original Image";
  13. }
  14. Button {
  15. anchors.right: parent.right;
  16. anchors.top: parent.top;
  17. anchors.margins: 4;
  18. text: "Back";
  19. onClicked: example.back();
  20. }
  21. Image {
  22. id: origImage;
  23. width: 240;
  24. height: 240;
  25. anchors.left: parent.left;
  26. anchors.top: origLabel.bottom;
  27. anchors.margins: 4;
  28. source: "butterfly.png";
  29. sourceSize: Qt.size(240, 240);
  30. smooth: true;
  31. }
  32. Rectangle{
  33. anchors.left: parent.left;
  34. anchors.leftMargin: 4;
  35. anchors.right: parent.right;
  36. anchors.rightMargin: 4;
  37. anchors.top: origImage.bottom;
  38. height: 2;
  39. border.width: 1;
  40. border.color: "darkgray";
  41. }
  42. Text {
  43. id: effectsLabel;
  44. anchors.top: origImage.bottom;
  45. anchors.margins: 4;
  46. anchors.left: parent.left;
  47. font.pointSize: 20;
  48. font.bold: true;
  49. text: "Shadow Effects:";
  50. color: "blue";
  51. }
  52. Rectangle {
  53. id: shadowEffects;
  54. anchors.left: effectsLabel.right;
  55. anchors.leftMargin: 4;
  56. anchors.top: effectsLabel.top;
  57. anchors.right: parent.right;
  58. anchors.rightMargin: 4;
  59. height: 40;
  60. color: "gray";
  61. ListView {
  62. anchors.fill: parent;
  63. clip: true;
  64. focus: true;
  65. orientation: ListView.Horizontal;
  66. spacing: 20;
  67. delegate: Text {
  68. id: wrapper;
  69. height: 40;
  70. verticalAlignment: Text.AlignVCenter;
  71. text: name;
  72. font.pointSize: 18;
  73. Keys.onEnterPressed: {
  74. event.accepted = true;
  75. effectControl.source = example;
  76. }
  77. Keys.onReturnPressed: {
  78. event.accepted = true;
  79. effectControl.source = example;
  80. }
  81. MouseArea {
  82. anchors.fill: parent;
  83. onClicked: {
  84. wrapper.ListView.view.currentIndex = index;
  85. effectControl.source = example;
  86. }
  87. }
  88. }
  89. highlight: Rectangle {
  90. height: parent.height;
  91. color: "lightblue";
  92. }
  93. model: shadowsModel;
  94. }
  95. }
  96. Loader {
  97. id: effectControl;
  98. anchors.top: shadowEffects.bottom;
  99. anchors.left: parent.left;
  100. anchors.bottom: parent.bottom;
  101. anchors.right: parent.right;
  102. anchors.margins: 4;
  103. source: "DropShadowEx.qml";
  104. }
  105. ListModel {
  106. id: shadowsModel;
  107. ListElement {
  108. name: "DropShadow";
  109. example: "DropShadowEx.qml";
  110. }
  111. ListElement {
  112. name: "InnerShadow";
  113. example: "InnerShadowEx.qml";
  114. }
  115. }
  116. }

DropShawExample.qml 会被“Qt Quick里的图形效果(Graphical Effects)”里介绍过的 main.qml 动态加载。

阴影效果

阴影效果对应的 DropShadowEx.qml 内容如下:

  1. import QtQuick 2.2
  2. import QtGraphicalEffects 1.0
  3. import QtQuick.Controls 1.2
  4. Rectangle {
  5. anchors.fill: parent;
  6. Image {
  7. id: opImage;
  8. x: 4;
  9. y: 4;
  10. width: 250;
  11. height: 250;
  12. source: "butterfly.png";
  13. sourceSize: Qt.size(250, 250);
  14. smooth: true;
  15. visible: false;
  16. }
  17. DropShadow {
  18. id: dropshadow;
  19. anchors.fill: opImage;
  20. source: opImage;
  21. }
  22. Rectangle {
  23. anchors.left: opImage.right;
  24. anchors.top: opImage.top;
  25. anchors.right: parent.right;
  26. anchors.bottom: parent.bottom;
  27. anchors.margins: 2;
  28. color: "lightsteelblue";
  29. CheckBox {
  30. id: fast;
  31. anchors.top: parent.top;
  32. anchors.topMargin: 4;
  33. anchors.left: parent.left;
  34. anchors.leftMargin: 4;
  35. checked: false;
  36. text: "fast";
  37. }
  38. CheckBox {
  39. id: transparentBorder;
  40. anchors.left: fast.right;
  41. anchors.leftMargin: 8;
  42. anchors.top: fast.top;
  43. checked: false;
  44. text: "transparentBorder";
  45. }
  46. Text {
  47. id: colorLabel;
  48. anchors.left: fast.left;
  49. anchors.top: fast.bottom;
  50. anchors.topMargin: 8;
  51. text: "shadow color:";
  52. }
  53. ColorPicker {
  54. id: shadowColor;
  55. anchors.left: colorLabel.right;
  56. anchors.leftMargin: 4;
  57. anchors.top: colorLabel.top;
  58. width: 90;
  59. height: 28;
  60. color: "#ff000000";
  61. }
  62. Text {
  63. id: sampleLabel;
  64. anchors.left: fast.left;
  65. anchors.top: shadowColor.bottom;
  66. anchors.topMargin: 8;
  67. text: "samples:";
  68. }
  69. Slider {
  70. id: sampleSlider;
  71. anchors.left: sampleLabel.right;
  72. anchors.leftMargin: 4;
  73. anchors.top: sampleLabel.top;
  74. minimumValue: 0;
  75. maximumValue: 32;
  76. value: 0.0;
  77. width: 160;
  78. height: 30;
  79. stepSize: 1.0;
  80. }
  81. Text {
  82. id: spreadLabel;
  83. anchors.left: fast.left;
  84. anchors.top: sampleSlider.bottom;
  85. anchors.topMargin: 8;
  86. text: "spread:";
  87. }
  88. Slider {
  89. id: spreadSlider;
  90. anchors.left: spreadLabel.right;
  91. anchors.leftMargin: 4;
  92. anchors.top: spreadLabel.top;
  93. value: 0.5;
  94. width: 160;
  95. height: 30;
  96. }
  97. Text {
  98. id: radiusLabel;
  99. anchors.left: fast.left;
  100. anchors.top: spreadSlider.bottom;
  101. anchors.topMargin: 8;
  102. text: "radius:";
  103. }
  104. Rectangle {
  105. id: radiusArea;
  106. anchors.left: radiusLabel.right;
  107. anchors.leftMargin: 4;
  108. anchors.top: radiusLabel.top;
  109. height: 30;
  110. width: 160;
  111. color: "lightgray";
  112. border.width: 1;
  113. border.color: "darkgray";
  114. TextInput {
  115. anchors.fill: parent;
  116. anchors.margins: 2;
  117. id: radiusEdit;
  118. font.pointSize: 18;
  119. text: "0.0";
  120. validator: DoubleValidator{bottom: 0;}
  121. }
  122. }
  123. Text {
  124. id: voffLabel;
  125. anchors.left: fast.left;
  126. anchors.top: radiusArea.bottom;
  127. anchors.topMargin: 8;
  128. text: "verticalOffset:";
  129. }
  130. Rectangle {
  131. id: voffArea;
  132. anchors.left: voffLabel.right;
  133. anchors.leftMargin: 4;
  134. anchors.top: voffLabel.top;
  135. height: 30;
  136. width: 160;
  137. color: "lightgray";
  138. border.width: 1;
  139. border.color: "darkgray";
  140. TextInput {
  141. anchors.fill: parent;
  142. anchors.margins: 2;
  143. id: voffEdit;
  144. font.pointSize: 18;
  145. text: "0.0";
  146. validator: DoubleValidator{}
  147. }
  148. }
  149. Text {
  150. id: hoffLabel;
  151. anchors.left: fast.left;
  152. anchors.top: voffArea.bottom;
  153. anchors.topMargin: 8;
  154. text: "horizontalOffset:";
  155. }
  156. Rectangle {
  157. id: hoffArea;
  158. anchors.left: hoffLabel.right;
  159. anchors.leftMargin: 4;
  160. anchors.top: hoffLabel.top;
  161. height: 30;
  162. width: 160;
  163. color: "lightgray";
  164. border.width: 1;
  165. border.color: "darkgray";
  166. TextInput {
  167. anchors.fill: parent;
  168. anchors.margins: 2;
  169. id: hoffEdit;
  170. font.pointSize: 18;
  171. text: "0.0";
  172. validator: DoubleValidator{}
  173. }
  174. }
  175. Button {
  176. id: applyBtn;
  177. anchors.left: parent.left;
  178. anchors.leftMargin: 4;
  179. anchors.top: hoffArea.bottom;
  180. anchors.topMargin: 12;
  181. text: "Apply";
  182. onClicked: {
  183. dropshadow.color = shadowColor.color;
  184. dropshadow.fast = fast.checked;
  185. dropshadow.transparentBorder = transparentBorder.checked;
  186. dropshadow.samples = sampleSlider.value;
  187. dropshadow.radius = parseFloat(radiusEdit.text);
  188. dropshadow.verticalOffset = voffEdit.text;
  189. dropshadow.horizontalOffset = hoffEdit.text;
  190. dropshadow.spread = spreadSlider.value;
  191. }
  192. }
  193. }
  194. }

代码比较简单,不细说了。我们看看 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 内容如下:

  1. import QtQuick 2.2
  2. import QtGraphicalEffects 1.0
  3. import QtQuick.Controls 1.2
  4. Rectangle {
  5. anchors.fill: parent;
  6. Image {
  7. id: opImage;
  8. x: 4;
  9. y: 4;
  10. width: 250;
  11. height: 250;
  12. source: "butterfly.png";
  13. sourceSize: Qt.size(250, 250);
  14. smooth: true;
  15. visible: false;
  16. }
  17. InnerShadow {
  18. id: innershadow;
  19. anchors.fill: opImage;
  20. source: opImage;
  21. }
  22. Rectangle {
  23. anchors.left: opImage.right;
  24. anchors.top: opImage.top;
  25. anchors.right: parent.right;
  26. anchors.bottom: parent.bottom;
  27. anchors.margins: 2;
  28. color: "lightsteelblue";
  29. CheckBox {
  30. id: fast;
  31. anchors.top: parent.top;
  32. anchors.topMargin: 4;
  33. anchors.left: parent.left;
  34. anchors.leftMargin: 4;
  35. checked: false;
  36. text: "fast";
  37. }
  38. Text {
  39. id: colorLabel;
  40. anchors.left: fast.left;
  41. anchors.top: fast.bottom;
  42. anchors.topMargin: 8;
  43. text: "shadow color:";
  44. }
  45. ColorPicker {
  46. id: shadowColor;
  47. anchors.left: colorLabel.right;
  48. anchors.leftMargin: 4;
  49. anchors.top: colorLabel.top;
  50. width: 90;
  51. height: 28;
  52. color: "#ff000000";
  53. }
  54. Text {
  55. id: sampleLabel;
  56. anchors.left: fast.left;
  57. anchors.top: shadowColor.bottom;
  58. anchors.topMargin: 8;
  59. text: "samples:";
  60. }
  61. Slider {
  62. id: sampleSlider;
  63. anchors.left: sampleLabel.right;
  64. anchors.leftMargin: 4;
  65. anchors.top: sampleLabel.top;
  66. minimumValue: 0;
  67. maximumValue: 32;
  68. value: 0.0;
  69. width: 160;
  70. height: 30;
  71. stepSize: 1.0;
  72. }
  73. Text {
  74. id: spreadLabel;
  75. anchors.left: fast.left;
  76. anchors.top: sampleSlider.bottom;
  77. anchors.topMargin: 8;
  78. text: "spread:";
  79. }
  80. Slider {
  81. id: spreadSlider;
  82. anchors.left: spreadLabel.right;
  83. anchors.leftMargin: 4;
  84. anchors.top: spreadLabel.top;
  85. value: 0.5;
  86. width: 160;
  87. height: 30;
  88. }
  89. Text {
  90. id: radiusLabel;
  91. anchors.left: fast.left;
  92. anchors.top: spreadSlider.bottom;
  93. anchors.topMargin: 8;
  94. text: "radius:";
  95. }
  96. Rectangle {
  97. id: radiusArea;
  98. anchors.left: radiusLabel.right;
  99. anchors.leftMargin: 4;
  100. anchors.top: radiusLabel.top;
  101. height: 30;
  102. width: 160;
  103. color: "lightgray";
  104. border.width: 1;
  105. border.color: "darkgray";
  106. TextInput {
  107. anchors.fill: parent;
  108. anchors.margins: 2;
  109. id: radiusEdit;
  110. font.pointSize: 18;
  111. text: "0.0";
  112. validator: DoubleValidator{bottom: 0;}
  113. }
  114. }
  115. Text {
  116. id: voffLabel;
  117. anchors.left: fast.left;
  118. anchors.top: radiusArea.bottom;
  119. anchors.topMargin: 8;
  120. text: "verticalOffset:";
  121. }
  122. Rectangle {
  123. id: voffArea;
  124. anchors.left: voffLabel.right;
  125. anchors.leftMargin: 4;
  126. anchors.top: voffLabel.top;
  127. height: 30;
  128. width: 160;
  129. color: "lightgray";
  130. border.width: 1;
  131. border.color: "darkgray";
  132. TextInput {
  133. anchors.fill: parent;
  134. anchors.margins: 2;
  135. id: voffEdit;
  136. font.pointSize: 18;
  137. text: "0.0";
  138. validator: DoubleValidator{}
  139. }
  140. }
  141. Text {
  142. id: hoffLabel;
  143. anchors.left: fast.left;
  144. anchors.top: voffArea.bottom;
  145. anchors.topMargin: 8;
  146. text: "verticalOffset:";
  147. }
  148. Rectangle {
  149. id: hoffArea;
  150. anchors.left: hoffLabel.right;
  151. anchors.leftMargin: 4;
  152. anchors.top: hoffLabel.top;
  153. height: 30;
  154. width: 160;
  155. color: "lightgray";
  156. border.width: 1;
  157. border.color: "darkgray";
  158. TextInput {
  159. anchors.fill: parent;
  160. anchors.margins: 2;
  161. id: hoffEdit;
  162. font.pointSize: 18;
  163. text: "0.0";
  164. validator: DoubleValidator{}
  165. }
  166. }
  167. Button {
  168. id: applyBtn;
  169. anchors.left: parent.left;
  170. anchors.leftMargin: 4;
  171. anchors.top: hoffArea.bottom;
  172. anchors.topMargin: 12;
  173. text: "Apply";
  174. onClicked: {
  175. innershadow.color = shadowColor.color;
  176. innershadow.fast = fast.checked;
  177. innershadow.samples = sampleSlider.value;
  178. innershadow.radius = parseFloat(radiusEdit.text);
  179. innershadow.verticalOffset = voffEdit.text;
  180. innershadow.horizontalOffset = hoffEdit.text;
  181. innershadow.spread = spreadSlider.value;
  182. }
  183. }
  184. }
  185. }

源码比较简单,不说了。

InnerShadow 比 DropShadow 少了一个 transparentBorder 属性,其他基本一致,偷个懒,也不说了。

回顾一下:

Qt Quick里的图形效果:阴影(Drop Shadow)的更多相关文章

  1. Qt Quick实现的疯狂算数游戏

    使用 Qt Quick 写了个小游戏:疯狂算数.支持 Windows 和 Android 两个平台. 游戏简单,但牵涉到下面你的 Qt Quick 主题: 自己实现一个按钮 自适应分辨率 国际化 QM ...

  2. Qt Quick实现的涂鸦程序

    之前一直以为 Qt Quick 里 Canvas 才干够自绘.后来发觉不是,原来还有好几种方式都能够画图! 能够使用原始的 OpenGL(Qt Quick 使用 OpenGL 渲染).能够构造QSGN ...

  3. Qt Quick之StackView具体解释(1)

    Qt Quick中有个StackView.我在<Qt Quick核心编程>一书中没有讲到.近期有人问起,趁机学习了一下,把它的基本使用方法记录下来. 我准备分两次来讲.第一次讲主要的使用方 ...

  4. Qt Quick综合实例之文件查看器

    假设你基于Qt SDK 5.3.1来创建一个Qt Quick App项目,项目模板为你准备的main.qml文档的根元素是ApplicationWindow或Window.这次我们就以Applicat ...

  5. 《Qt Quick 4小时入门》学习笔记

    http://edu.csdn.net/course/detail/1042/14804?auto_start=1   Qt Quick 4小时入门 第五章:Qt Quick里的信号与槽   QML中 ...

  6. Qt5官方demo分析集11——Qt Quick Particles Examples - Affectors

    在这个系列中的所有文章都可以在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 接上文Qt5官方demo解析集10--Qt ...

  7. Qt Widgets、QML、Qt Quick的区别

    Qt Widgets.QML.Qt Quick的区别 简述 看了之前关于 QML 的一些介绍,很多人难免会有一些疑惑: Q1:QML 和 Qt Quick 之间有什么区别? Q2:QtQuick 1. ...

  8. 浏览器上的Qt Quick

    你想不想在浏览器上运行你的Qt Quick程序呢?在Qt 5.12之前,唯一的方法是使用Qt WebGL Streaming技术把界面镜像到浏览器上.但该方法有不少缺陷,下文会说.前不久随着Qt 5. ...

  9. Qt on Android: Qt Quick 之 Hello World 图文具体解释

    在上一篇文章,<Qt on Android:QML 语言基础>中,我们介绍了 QML 语言的语法,在最后我们遗留了一些问题没有展开,这篇呢,我们就正式開始撰写 Qt Quick 程序,而那 ...

随机推荐

  1. VB VBA VBS有什么区别?

    VB和VBA本就是同宗的姐妹,只不过姐姐VB的功夫要比妹妹VBA历害些.不过姐姐只会单打独斗是女强人:妹妹却只会傍大款(例如Office).姐姐有生育能力,是真正的女人:妹妹却不会生崽(生成.EXE) ...

  2. ubuntu显卡驱动安装及设置

    转自: Ubuntu 14.04 Nvidia显卡驱动安装及设置   更换主板修复grub 引导后,无法从Nvidia进入系统(光标闪烁), 可能是显卡驱动出了问题. 1. 进入BIOS设置, 从集成 ...

  3. php 异步

    .post(handle,{username: username.val(),content: content.val()},function(data){ },'json');

  4. Spring Security(11)——匿名认证

    目录 1.1     配置 1.2     AuthenticationTrustResolver 对于匿名访问的用户,Spring Security支持为其建立一个匿名的AnonymousAuthe ...

  5. Spring的Bean之Bean的基本概念[转]

    从前面我们知道Spring其实就是一个大型的工厂,而Spring容器中的Bean就是该工厂的产品.对于Spring容器能够生产那些产品,则取决于配置文件中配置. 对于我们而言,我们使用Spring框架 ...

  6. js提交form表单

    <form action="/Enterprise/member" id="sendinviteid" method="post"&g ...

  7. 可靠通信的保障 —— 使用ACK机制发送自定义信息——ESFramework 通信框架4.0 快速上手(12)

    使用ESPlus.Application.CustomizeInfo.Passive.ICustomizeInfoOutter接口的Send方法,我们已经可以给服务端或其它在线客户端发送自定义信息了, ...

  8. Excel教程(12) - 数学和三角函数

    ABS     用途:返回某一参数的绝对值.   语法:ABS(number) 参数:number 是需要计算其绝对值的一个实数. 实例:如果 A1=-16,则公式"=ABS(A1)&quo ...

  9. USB 设备插拔事件处理

            Windows 系统下,设备连接至电脑或从电脑移除,系统会广播一条 WM_DEVICECHANGE 消息到所有应用程序,在程序的消息处理函数中可以对事件进行相应. 1: class C ...

  10. id和instancetype的异同

    相同点: 都可以作为方法返回值类型 在initWithName:方法中是一样的,例如: - (id)initWithName:(NSString *)name; - (instancetype)ini ...