一、效果展示

  如本文的标题所示,这篇文章分析的demo是一个异形窗口,主要展示鼠标在和异形区域交互的使用,效果如图1所示,当鼠标移动到白云或者月亮上时,相应的物体会高亮,当鼠标按下时,物体会有一个放大的动画效果,鼠标离开时恢复原样。

图1 月亮和云朵

二、源码分析

  正式算起来,这是我分析的第五篇qml示例程序了,在这里他么有一个共同点,qml控件直接展示不了的东西都是使用C++类或者js函数来完成,比如这篇文章要讲的异形区域判断;qml demo分析(customgeometry-贝塞尔曲线)文章中的贝塞尔曲线绘制;qml demo分析(maroon-小游戏)小游戏中的代码复杂逻辑使用js控制;qml demo分析(abstractitemmodel-数据分离)示例中的model结构等。那么从这几篇文章中我们也能体会到qml不是一个人在战斗,他更多的是在于ui展示,而具体的逻辑或者更为复杂的操作需要交给C++程序或者js代码来完成,关于C++和qml混合编程、js和qml混合编程之前的代码都有涉及,不了解的同学可以直接点击相关链接进入。

  本篇示例代码相对来说比较简单,主要就是两部分:qml和C++

1、qml代码

  qml代码中总共有3张图片,先添加的图片在下层显示,如果你想要让某一张图片在上次显示那么就需要在最后添加该组件。这3张图片的行为是一模一样,因此我只分析月亮这一个组件,代码如下

 1     //后添加的元素在上
 2     Image {
 3         id: moon
 4         anchors.centerIn: parent
 5         scale: moonArea.pressed ? 1.1 : 1.0//按下时  放大
 6         opacity: moonArea.containsMouse ? 1.0 : 0.7//hover时 无透明度
 7         source: Qt.resolvedUrl("images/moon.png")
 8
 9         MaskedMouseArea {//自定义组件   新增鼠标是否按下判断、鼠标是否在区域内
10             id: moonArea
11             anchors.fill: parent
12             alphaThreshold: 0
13             maskSource: moon.source
14         }
15
16         Behavior on opacity {//透明度使用渐变
17             NumberAnimation { duration: 200 }
18         }
19         Behavior on scale {//放大使用渐变
20             NumberAnimation { duration: 100 }
21         }
22     }

  上述代码就是qml中关于月亮的展示,MaskedMouseArea组件是使用qmlRegisterType宏注册到qml系统中的。本篇文章我就不在讲解main函数了,如果忘记的同学可以到qml demo分析(customgeometry-贝塞尔曲线)文章中回顾。

2、C++代码

  本篇文章有一个自定义的C++类,主要是给qml程序提供鼠标按下、鼠标hover等状态,头文件如下

 1 #include <QImage>
 2 #include <QQuickItem>
 3
 4 class MaskedMouseArea : public QQuickItem
 5 {
 6     Q_OBJECT
 7     Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged)
 8     Q_PROPERTY(bool containsMouse READ containsMouse NOTIFY containsMouseChanged)
 9     Q_PROPERTY(QUrl maskSource READ maskSource WRITE setMaskSource NOTIFY maskSourceChanged)
10     Q_PROPERTY(qreal alphaThreshold READ alphaThreshold WRITE setAlphaThreshold NOTIFY alphaThresholdChanged)
11
12 public:
13     MaskedMouseArea(QQuickItem *parent = 0);
14
15     bool contains(const QPointF &point) const;//重写contains接口 判断鼠标是否在在异形窗口内 默认实现判断参数点是否在bounding rect内
16
17     //鼠标是否按下 配合Q_PROPERTY宏  可以被qml系统调用 例如:scale: rightCloudArea.pressed ? 1.1 : 1.0
18     bool isPressed() const { return m_pressed; }
19     bool containsMouse() const { return m_containsMouse; }
20
21     QUrl maskSource() const { return m_maskSource; }
22     void setMaskSource(const QUrl &source);
23
24     qreal alphaThreshold() const { return m_alphaThreshold; }
25     void setAlphaThreshold(qreal threshold);
26
27 signals:
28     void pressed();//自定义信号  在qml系统中均有OnPressed槽
29     void released();
30     void clicked();
31     void canceled();
32     void pressedChanged();
33     void maskSourceChanged();
34     void containsMouseChanged();
35     void alphaThresholdChanged();
36
37 protected:
38     void setPressed(bool pressed);
39     void setContainsMouse(bool containsMouse);
40
41     void mousePressEvent(QMouseEvent *event);
42     void mouseReleaseEvent(QMouseEvent *event);
43
44     void hoverEnterEvent(QHoverEvent *event);
45     void hoverLeaveEvent(QHoverEvent *event);
46
47     void mouseUngrabEvent();
48
49 private:
50     bool m_pressed;
51     QUrl m_maskSource;
52     QImage m_maskImage;
53     QPointF m_pressPoint;
54     qreal m_alphaThreshold;
55     bool m_containsMouse;
56 };

  头文件中的Q_PROPERTY如果忘记其含义,可以到qml demo分析(customgeometry-贝塞尔曲线)文章中了解,其中每一个Q_PROPERTY宏第一个参数为属性,READ指定读取属性的接口,WRITE指定设置属性的接口,NOTIFY指定当属性改变时所触发的信号,当然了这个属性还有更多的其他功能,感兴趣的同学可以自行上帮助文档查阅。

 1 bool MaskedMouseArea::contains(const QPointF &point) const
 2 {
 3     if (!QQuickItem::contains(point) || m_maskImage.isNull())
 4         return false;
 5
 6     QPoint p = point.toPoint();
 7
 8     if (p.x() < 0 || p.x() >= m_maskImage.width() ||
 9         p.y() < 0 || p.y() >= m_maskImage.height())
10         return false;
11
12     qreal r = qBound<int>(0, m_alphaThreshold * 255, 255);
13     return qAlpha(m_maskImage.pixel(p)) > r;//根据alpha值判断 异形区域
14 }

  自定义QQuickItem类,最重要的是判断鼠标是否在区域内,也就是contains函数,该函数默认是判断鼠标是否在组件所在矩形区域,为了让交互行为更好,我们需要让鼠标在月亮的圆上或者云朵内才高亮物体,因此我们重写了次接口,该接口是用图片的alpha值来判断,当该值达到一定透明度时,认为其不在区域内,具体代码如上所示。

  这篇示例代码在Qt5.7.0_vs2013\Examples\Qt-5.7\quick\customitems\maskedmousearea目录下。我使用的qt5.6.1-1版本,该版本为自行编译版本,编译参考:msvc2013编译qt5.6源码

三、相关文章

  qml demo分析(abstractitemmodel-数据分离)

  qml demo分析(clocks-时钟)

  qml demo分析(customgeometry-贝塞尔曲线)

  qml demo分析(maroon-小游戏)

转载于:https://www.cnblogs.com/swarmbees/p/6519613.html

qml demo分析(maskedmousearea-异形窗口)相关推荐

  1. qml demo分析(threadedanimation-线程动画)

    一.效果预览 使用过qml的同学都知道,使用qml做动画效果是非常简单的,再也不需要像QWidget那样,自己模拟一个动画,费时又费力,往往还达不到效果.今天我们就来分析下qml的两种动画实现方式,如 ...

  2. qml demo分析(clocks-时钟)

    一.效果展示 效果如图1所示,时钟列表支持鼠标左右拖动,带有黑色背景的是晚上时钟,无黑色背景的是白天时钟 二.源码分析 1.main.cpp文件中只包含了一个宏,该宏的具体解释请看qml 示例中的关键 ...

  3. qml demo分析(threading-线程任务)

    一.关键类说明 qml内置了WorkerScript组件,该组件有一个source属性,可以加载js文件,含有一个名为message的信号,意味着他有一个默认的onMessage槽函数,除此之外他还有 ...

  4. qml demo分析(customgeometry-贝塞尔曲线)

    一.效果展示 本篇文章还是带来一个简单的qt示例分析,且看图1效果. 图1 贝塞尔曲线 二.源码分析 该示例代码所在目录quick\scenegraph\customgeometry,感兴趣的同学可以 ...

  5. wpf异形按钮_WPF Window异形窗口演示

    我们先通过简单的效果展示,切换展示不同图片: 我们先定义图片资源文件,我们可以在window资源中定义,下面的在app.xaml文件来定义: xmlns="http://schemas.mi ...

  6. WPF 制作高性能的透明背景异形窗口(使用 WindowChrome 而不要使用 AllowsTransparency=True)

    在 WPF 中,如果想做一个背景透明的异形窗口,基本上都要设置 WindowStyle="None".AllowsTransparency="True" 这两个 ...

  7. [MFC] WS_EX_LAYERED 实现透明异形窗口(酷狗歌词、360加速球、窗口边缘阴影)

    关键词:WS_EX_LAYERED. UpdateLayeredWindow PC应用不少都有透明的异形窗口  比如以下程序的效果: 酷狗音乐播放器的歌词窗口(窗口除了歌词内容 其他都是透明的) 36 ...

  8. DUILIB异形窗口实现

    搞Windows程序的人尽皆知分层窗口能够实现很多不错的效果,之前看过一些异形窗口的实现,所以就手痒也想自己搞一个玩一玩.自己动手实现过程才发现还是有不少问题的. 基本思路是: 1.将窗口扩展属性设置 ...

  9. SDL2源代码分析2:窗口(SDL_Window)

    ===================================================== SDL源代码分析系列文章列表: SDL2源代码分析1:初始化(SDL_Init()) SDL ...

  10. go-pitaya学习笔记(9)-rate_limiting demo分析

    学习笔记: 我家别墅靠大海/pitaya-learn 尝试集成功能:我家别墅靠大海/pitaya-game 如果你正在看此笔记,请你左边放笔记,右边放chatdemo的代码!! 我是按代码的顺序记的笔 ...

最新文章

  1. leangoo领歌看板工具新增任务到期提醒功能
  2. 高产来自“长期主义”:智源学者朱军谈ICLR 2020 全球发文第二的经验法则
  3. # 管道已结束_CIPP内衬紫外线固化法用于污水管道非开挖修复
  4. jspServlet(2)
  5. ASP.NET Core和json请求这样用真简单,axios、微信小程序得救了
  6. Java中的XSL转换:一种简单的方法
  7. 3d打印光固化好还是热固化好_UV专利一览(71) —天啦噜!3D打印上太空!
  8. 【转载保存】java8新特性学习
  9. 将json字符串转换成html,将JSON HTML字符串转换为HTML
  10. Linux的Vim编辑器
  11. vue 修改项目启动后的页面_vue项目打包后打开页面空白解决办法
  12. 数组的合并和升序排列_每日“力扣”系列10 下一个排列
  13. 刚刚申请的博客,自己也是新手!
  14. ftp上传当天文件的方法_8uftp上传工具,8uftp上传工具的使用方法只需8步
  15. 杭电acm2012 素数判定
  16. 第一次参加公司研发部门高级别会议之感
  17. python火车票票价_Python火车票代码
  18. flask入门和进阶五(关注功能的实现Followers)
  19. 【canvas画图】画一个彩虹
  20. 99%的人不知道大数据分析现状是什么,主要的分析技术是什么?

热门文章

  1. 模板题——贪心(2)
  2. ENVI-IDL基础学习(1)
  3. Vite Vue项目加载Cesium模块
  4. 数据结构与算法------插入排序
  5. 原生Hadoop集群搭建过程记录
  6. Python基础语法-01-类及对象
  7. Linux关闭占用端口的进程
  8. Flutter之跨组件共享状态Provider原理剖析
  9. android MVC和MVP探讨
  10. java中的堆和栈_实例理解Java中的堆和栈