首页 > 代码库 > Qt Quick里的图形效果——混合(Blend)
Qt Quick里的图形效果——混合(Blend)
Blend 元素用指定的模式混合两个 Item 。在我们使用 QPainter 绘图时,支持 Composition Modes ,Blend 干的事儿与此类似。
使用 Blend 需要:
import QtGraphicalEffects 1.0
博客之星评选,点击投我一票,谢谢。投过了也可以点哦,每天都可以投投一票。
Blend元素简介
Blend 是 Item 的派生类,有下列属性:
- source,指定源Item
- foregroundSource,指定作为前景的源 Item
- mode,一个字符串,指定要使用的混合模式
- cached,布尔变量,默认值为 false 。设置为 true ,可以缓存输出的效果图像,提升渲染效率,不过会占用更多的内存。如果源 Item 具有动态效果,建议禁用 cache 。
Blend 元素本身是一个 Item ,你可以使用 anchors 来对它布局,也可以使用 x 、 y 、 width 、 height 等调整它的大小和位置。
下面是 Qt 帮助里的示例代码:
import QtQuick 2.2 import QtGraphicalEffects 1.0 Item { width: 300 height: 300 Image { id: bug source: "images/bug.jpg" sourceSize: Qt.size(parent.width, parent.height) smooth: true visible: false } Image { id: butterfly source: "images/butterfly.png" sourceSize: Qt.size(parent.width, parent.height) smooth: true visible: false } Blend { anchors.fill: bug source: bug foregroundSource: butterfly mode: "subtract" } }
如代码所示,Blend 对象指定了 source 、 foregroundSource 、 mode 三个属性。
注意到 anchors.fill 属性了吗,它产生效果是: Blend 元素占据 bug 的位置,并且充满它。那实际上在定义 Blend 对象时也可以这样:
Blend { anchors.top: parent.top; anchors.right: parent.right; width: 240; height: 240; source: bug; foregroundSource: butterfly; mode: "subtract"; }
值得一提的是,如果使用锚布局来定位 Blend 对象,那它锚定的 Item 必须是 Blend 的父或者兄弟。
如你所见,示例代码将 bug 和 butterfly 的 visible 属性设置为 false ,这并不是必须的。如果我们将 Blend 元素当作是 source 、 foregroundSource 根据 mode 混合后的那个元素,理解起来就会容易得多。Blend 、 source 、 foregroundSource 是三个逻辑上相互独立的元素,你可以随意摆布它们,它们的位置、可见属性等相互没有任何影响。
Blend示例
BlendExample.qml 演示了各种混合模式。效果图如下:
图 1 混合示例效果图
如图 1 所示,界面分成两部分,上方是原始图片,下方是混合效果。
我使用一个 ListView 展示 Blend 支持的所有混合模式,在 ListView 右侧显示混合结果,当选中 ListView 内的条目时,动态改变 Blend 的 mode 属性,Blend 就会重新混合两个源 Item ,我们就能看到新的混合效果。
下面是 BlendExample.qml :
import QtQuick 2.2 import QtGraphicalEffects 1.0 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 Images"; } Button { anchors.right: parent.right; anchors.top: parent.top; anchors.margins: 4; text: "Back"; onClicked: example.back(); } Row { id: origImages; width: 500; height: 260; anchors.left: parent.left; anchors.top: origLabel.bottom; anchors.margins: 4; spacing: 10; Image { source: "bug.jpg"; sourceSize: Qt.size(240, 240); smooth: true; } Image { 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: origImages.bottom; height: 2; border.width: 1; border.color: "darkgray"; } Text { id: blendLabel; anchors.top: origImages.bottom; anchors.margins: 4; anchors.left: parent.left; font.pointSize: 20; font.bold: true; text: "Blend Modes && Effects"; color: "blue"; } Rectangle { id: blendModes; anchors.left: parent.left; anchors.leftMargin: 4; anchors.top: blendLabel.bottom; anchors.topMargin: 10; anchors.bottom: parent.bottom; anchors.bottomMargin: 4; width: 160; color: "gray"; ListView { anchors.fill: parent; clip: true; focus: true; delegate: Text { id: wrapper; text: name; width: parent.width; height: 36; font.pointSize: 20; Keys.onEnterPressed: { blender.mode = name; event.accepted = true; } Keys.onReturnPressed: { blender.mode = name; event.accepted = true; } MouseArea { anchors.fill: parent; onClicked: { wrapper.ListView.view.currentIndex = index; blender.mode = name; } } } highlight: Rectangle { width: parent.width; color: "lightblue"; } model: modesModel; } } Image { id: bug; anchors.top: blendLabel.bottom; anchors.topMargin: 10; anchors.left: blendModes.right; anchors.leftMargin: 10; source: "bug.jpg"; sourceSize: Qt.size(300, 300); smooth: true; visible: false; } Image { id: bufferFly; source: "butterfly.png"; sourceSize: Qt.size(300, 300); smooth: true; visible: false; } Blend { id: blender; source: bug; anchors.fill: bug; foregroundSource: bufferFly; mode: "subtract"; } ListModel { id: modesModel; ListElement { name: "subtract"; } ListElement { name: "normal"; } ListElement { name: "addition"; } ListElement { name: "average"; } ListElement { name: "colorBurn"; } ListElement { name: "color"; } ListElement { name: "colorDodge"; } ListElement { name: "darken"; } ListElement { name: "darkerColor"; } ListElement { name: "difference"; } ListElement { name: "divide"; } ListElement { name: "exclusion"; } ListElement { name: "hardLight"; } ListElement { name: "hue"; } ListElement { name: "lighten"; } ListElement { name: "lighterColor"; } ListElement { name: "lightness"; } ListElement { name: "multiply"; } ListElement { name: "negation"; } ListElement { name: "saturation"; } ListElement { name: "screen"; } ListElement { name: "softLight"; } } }
简单的分析一下代码。
返回
图 1 右上角有一个 “Back” 按钮,点击后会发射一个 back() 信号。 back 信号用来通知我们在“Qt Quick里的图形效果(1)”中提到的 main.qml :用户要从当前示例返回了。 main.qml 收到 back 信号时,会销毁动态创建的示例组件。
以后我们看到 ColorExample 等等针对某类效果设计的示例,都使用同一种策略。
混合
混合模式列表使用 ListView 的展示,ListElement 只有一个角色——name,它的值就是混合模式的名字。当用户点击列表中的某个条目时, delegate 的 MouseArea 的 onClicked 信号处理器改变 Blend 元素的 mode 属性。
好了,这次就到这里,每种混合模式效果如何,还请运行示例实际看一下。下次我们会介绍颜色(Color)效果。
博客之星评选,点击投我一票,谢谢。投过了也可以点哦,每天都可以投投一票。
--------
回顾一下我的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里的图形效果(Graphical Effects)
Qt Quick里的图形效果——混合(Blend)