Qt Quick里的图形成效(Graphical Effects)
Qt Quick 提供了 Graphical Effects ,我在《Qt Quick核心编程》一书中限于篇幅没有介绍,这里补上吧。
Graphical Effects ,姑且叫作图形效果吧。它提供了 Blend 、 Color 等好几类效果,有些类别下面又有多种不同的效果,要介绍完整需要较长的篇幅。我们一个一个来看。
博客之星评选,点击投我一票,谢谢。投过了也可以点哦,每天都可以投投一票。
概要介绍
先看看都有哪几类图形效果(Graphical Effects)吧:
- Blend,混合。只有一种类型——Blend,使用一种混合模式来合并两个源 items 。
- Color,颜色,通过改变一个 Item 的颜色来产生各种各样的效果。有下列几种类型:
- BrightnessContrast,调整亮度和对比度
- ColorOverlay,在源 Item 上覆盖一层颜色
- Colorize,设置源 Item 的 HSL 颜色空间
- Desaturate,降低颜色的饱和度
- GammaAdjust,使用 gamma 曲线来改变源 Item 的照度
- HueSaturation,在 HSL 颜色空间改变源 Item 的颜色
- LevelAdjust,在 RGBA 颜色空间调整源 Item 的颜色水平
- Gradient,渐变。有下列几种类型:
- ConicalGradient,锥形渐变
- LinearGradient,线性渐变
- RadialGradient,径向渐变
- Distortion,变形。只有一种类型——Displace,根据给定的位移 map 来改变源 Item 的像素
- Drop Shadow,投影。有两种类型:
- DropShadow,根据源 Item 产生一个彩色的、模糊的影子图像,并且把它放到原始图像的后面,会产生源 Item 在背景上凸起的效果
- InnerShadow,在源 Item 里面产生一个彩色的、模糊的图像
- Blur,模糊。有下面几种类型:
- FastBlur,快速模糊
- GaussianBlur,高斯模糊
- MaskedBlur,差异化模糊,可以根据一个掩码元素对源 Item 的不同区域产生强度不同的模糊效果
- RecursiveBlur,递归模糊。通过反复模糊来产生很强的模糊效果。
- Motion Blur,运动模糊。有下面几种类型:
- DirectionalBlur,定向模糊,在指定的方向上产生模糊效果
- RadialBlur,径向模糊,在以源 Item 的中心点为圆心的一个圆形内应用定向模糊
- ZoomBlur,缩放模糊,朝着源 Item 的中心点应用定向模糊
- Glow,发光。有下面几种类型:
- Glow,根据源 Item 产生一个彩色的、模糊的发光效果图像,并且把它放到源 Item 后面,产生一种源 Item 在发光的效果。
- RectangularGlow,生成一个模糊的、彩色的矩形,给人发光的印象
- Mask,遮罩。有下面几种类型:
- OpacityMask,透明遮罩。用另一个 Item 遮挡源 Item
- ThresholdMask,阈值遮罩。用另一个 Item 遮挡源 Item,根据一个阈值来应用遮挡效果
示例项目
我设计了一个示例来演示所有的图形效果,它是一个 Qt Quick App 项目。下面是示例运行后的首页:
图 1 示例首页
我们结合图 1 来介绍一下示例项目的结构。
如图 1 所示,首页中间是一个列表,列出了所有的图形效果类别。
界面底部右侧有两个按钮,“Load Examples”按钮用于加载选中的图形效果对应的示例。“Quit”就是退出了。
源码
首页的源码在 main.qml 中:
import QtQuick 2.2 import QtQuick.Window 2.1 import QtQuick.Controls 1.2 Window { id: appWin; visible: true; width: 640; height: 640; minimumWidth: 640; minimumHeight: 640; color: "lightgray"; property var currentExample: null; Text { id: clue; text: "Graphical Effects Examples"; anchors.top: parent.top; anchors.left: parent.left; anchors.margins: 4; font.pointSize: 24; font.bold: true; } Rectangle{ anchors.left: clue.left; anchors.right: parent.right; anchors.rightMargin: 4; anchors.top: clue.bottom; height: 2; border.width: 1; border.color: "darkgray"; } Component { id: exampleDelegate; Rectangle { id: wrapper; width: parent.width; height: 40; color: "transparent"; Text { anchors.fill: parent; text: name; color: wrapper.ListView.isCurrentItem ? "blue" : "steelblue"; font.pointSize: 20; verticalAlignment: Text.AlignVCenter; } MouseArea { anchors.fill: parent; onClicked: { wrapper.ListView.view.currentIndex = index; } } } } ListView { id: examples; anchors.bottom: quit.top; anchors.top: clue.bottom; anchors.left: parent.left; anchors.right: parent.right; anchors.margins: 8; clip: true; delegate: exampleDelegate; highlight: Rectangle { color: "lightblue"; width: parent.width; } model: ListModel { ListElement { name: "Blend"; example: "BlendExample.qml"; } ListElement { name: "Color"; example: "ColorExample.qml"; } ListElement { name: "Gradient"; example: "GradientExample.qml"; } ListElement { name: "Distortion"; example: "DistortionExample.qml"; } ListElement { name: "Drop Shadow"; example: "DropShadowExample.qml"; } ListElement { name: "Blur"; example: "BlurExample.qml"; } ListElement { name: "Motion Blur"; example: "MotionBlurExample.qml"; } ListElement { name: "Glow"; example: "GlowExample.qml"; } ListElement { name: "Mask"; example: "MaskExample.qml"; } } } Button { id: load; text: "Load Examples"; anchors.right: quit.left; anchors.top: quit.top; anchors.rightMargin: 8; onClicked: { var data = examples.model.get(examples.currentIndex); console.log("example: " , data.example); var comp = Qt.createComponent(data.example); if(comp.status == Component.Ready){ appWin.currentExample = comp.createObject(appWin, {"color" : appWin.color}); appWin.currentExample.back.connect(appWin.closeCurrentExample); } } } Button { id: quit; text: "Quit"; anchors.bottom: parent.bottom; anchors.right: parent.right; anchors.margins: 8; onClicked: Qt.quit(); } function closeCurrentExample() { currentExample.destroy(); } }
源码比较简单,从设计上解释一下。
列表视图
ListView列出了所有的图形效果。
exampleDelegate 这个组件用于绘制 ListView 里的一个 Item 。它接受并处理鼠标事件,改变 ListView 的当前 Item ;也改变当前 Item 的文本显示效果。
ListModel 非常简单,只是使用 ListElement 列出了所有图形效果的名字(角色名为name)和对应的示例文档(角色名为example),在 delegate 中我们可以通过角色名访问 Model 中的数据。
这就是 ListView 了: view + model + delegate ,非常灵活。更详细的用法,可以参考我的书《Qt Quick核心编程》,里面对 ListView 有超级详细的介绍。
动态加载图形效果
我给每一类图形效果提供了一个单独的演示界面,在 ListModel 内, example 这个角色保存了对应的示例 QML 文档的名字。当用户点击“Load Examples”按钮时,我获取到 ListView 的当前 Item ,通过 Model 取出数据,访问 example 角色,得到实际的 QML 文档名字,然后使用 Qt.createComponent() 和 Component.createObject() 来加载 QML 文档并生成示例组件。
好啦,这次就先介绍到这里,下一次我们介绍 混合效果。
博客之星评选,点击投我一票,谢谢。投过了也可以点哦,每天都可以投投一票。
--------
回顾一下我的Qt Quick系列文章:
- Qt Quick 简介
- QML 语言基础
- Qt Quick 之 Hello World 图文详解
- Qt Quick 简单教程
- Qt Quick 事件处理之信号与槽
- Qt Quick事件处理之鼠标、键盘、定时器
- Qt Quick 事件处理之捏拉缩放与旋转
- Qt Quick 组件与对象动态创建详解
- Qt Quick 布局介绍
- Qt Quick 之 QML 与 C++ 混合编程详解
- Qt Quick 图像处理实例之美图秀秀(附源码下载)
- Qt Quick 之 PathView 详解
- Qt Quick实例之挖头像
- Qt Quick综合实例之文件查看器
- Qt Quick调试之显示代码行号
- Qt Quick实现的涂鸦程序
- Qt Quick播放GIF动画
- Qt Quick 中的 drag and drop(拖放)
- Qt Quick里的AnimatedSprite的用法
- Qt Quick里的粒子系统
- Qt Quick实现的疯狂算数游戏
- Qt Quick里的图形效果——混合(Blend)