QML中的MouseArea类型为用户进行简单的鼠标操作提供了方便。

MouseArea是一个不可见的Item,通常与可见项目结合使用,以便为该项目提供鼠标处理。通过有效地充当代理,鼠标处理的逻辑可以包含在MouseArea Item中。

MouseArea虽然是一个不可见的Item,但是它有一个“visible”属性,当该属性为假时,鼠标区域就对鼠标事件变得透明。

MouseArea使用实例:

main.qml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 

Window
{
    id : window
    visible : true
    width : 
    height : 
    title : qsTr("Mouse Area")

Rectangle
    {
        id : rect
        anchors.left : window.left
        anchors.leftMargin : 
        width : ;
        height : 
        color : "green"

MouseArea
        {
            anchors.fill : parent
            onClicked :
            {
                parent.color = 'red';
            }
        }
    }

Rectangle
    {
        id : roundrect
        anchors.left : rect.right
        anchors.leftMargin : 
        width : ;
        height : 
        color : "red"
        radius :

MouseArea
        {
            anchors.fill : parent
            onClicked :
            {
                parent.color = 'green'
            }
        }
    }
}

常规测试实验证实,MouseArea有一个矩形的形状区域,这就会导致一些不是矩形形状的Item不能有效地获取实际形状的鼠标操作区域。如圆角矩形,在圆形按钮周围的假想方块的角落的鼠标操作也会被捕获,这显然不符合精准拾取的现实。

进阶地,文章“How to create a round mouse area in QML“提供了一种圆形鼠标区域RoundMouseArea:

RoundMouseArea.qml 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 

Item {
    id: roundMouseArea

property alias mouseX: mouseArea.mouseX
    property alias mouseY: mouseArea.mouseY

property bool containsMouse: {
        ;
        ;
        var x2 = mouseX;
        var y2 = mouseY;
        );
        );
        var isWithinOurRadius = distanceFromCenter < radiusSquared;
        return isWithinOurRadius;
    }

readonly property bool pressed: containsMouse && mouseArea.pressed

signal clicked

MouseArea {
        id: mouseArea
        anchors.fill: parent
        hoverEnabled: true
        acceptedButtons: Qt.LeftButton | Qt.RightButton
        onClicked: if (roundMouseArea.containsMouse) roundMouseArea.clicked()
    }
}

main.qml中使用:

main.qml片段 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
RoundMouseArea {
    id : roundMouseArea
    width : 
    height : 
    anchors.centerIn : parent

onClicked : print("clicked")

// Show the boundary of the area and whether or not it's hovered.
    Rectangle     {
        color : roundMouseArea.pressed ? "red" : (roundMouseArea.containsMouse ? "darkorange" : "transparent")
        border.color : "darkorange"
        radius : width / 
        anchors.fill : parent
    }
}

我们可以根据需要重写containsMouse来规定自己的鼠标区域,但是需要计算不同区域的数学知识,需要一定的功底。

再进一步,应该把鼠标区域一般化,可以使用任意的路径形状来表示才好。Qt自带一个例子maskedmousearea,此示例提供了一种使用任何形状的Mask的方法,它可以根据您的需求进行定制。

先睹为快:

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

class MaskedMouseArea : public QQuickItem

核心主要时判断鼠标点是否在图片有效区域内:

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
bool MaskedMouseArea::contains(const QPointF &point) const
{
    if (!QQuickItem::contains(point) || m_maskImage.isNull())
        return false;

QPoint p = point.toPoint();

|| p.x() >= m_maskImage.width() ||
            p.y() <  || p.y() >= m_maskImage.height())
        return false;

qreal r = qBound<);
    //根据alpha值判断 异形区域
    return qAlpha(m_maskImage.pixel(p)) > r;
}

 qml Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 
Image {
    id : moon
    anchors.centerIn : parent
    scale : moonArea.pressed ? 
    opacity : moonArea.containsMouse ? 
    source : Qt.resolvedUrl("images/moon.png")

MaskedMouseArea {
        id : moonArea
        anchors.fill : parent
        alphaThreshold : 
        maskSource : moon.source
    }

Behavior on opacity {
        NumberAnimation {
            duration : 
        }
    }
    Behavior on scale {
        NumberAnimation
        {
            duration : 
        }
    }
}

gif走起来:

QML MouseArea学习小结的更多相关文章

  1. qml基础学习 模型视图(一)

    一.理解qml模型和视图 qt的发展是迅速的,虽然在每一个release版本中或多或少都有bug,但是作为一个庞大的gui库,no,应该说是一个开发框架开说,qt已经算是做的相当好.qml部分是qt4 ...

  2. flex学习小结

    接触到flex一个多月了,今天做一个学习小结.如果有知识错误或者意见不同的地方.欢迎交流指教. 画外音:先说一下,我是怎么接触到flex布局的.对于正在学习的童鞋们,我建议大家没事可以逛逛网站,看看人 ...

  3. Python 学习小结

    python 学习小结 python 简明教程 1.python 文件 #!/etc/bin/python #coding=utf-8 2.main()函数 if __name__ == '__mai ...

  4. react学习小结(生命周期- 实例化时期 - 存在期- 销毁时期)

    react学习小结   本文是我学习react的阶段性小结,如果看官你是react资深玩家,那么还请就此打住移步他处,如果你想给一些建议和指导,那么还请轻拍~ 目前团队内对react的使用非常普遍,之 ...

  5. qml基础学习 Canvas画笔

    一.画布元素 自qt4.7发布qml以来,qml也在一直不断的完善中,在qt4时代使用qml时如果需要异形图,那我们只能让设计师来切图,这样的感觉是很不爽的,总感觉开发没有那么犀利.但是到了qt5这一 ...

  6. objective-c基础教程——学习小结

    objective-c基础教程——学习小结   提纲: 简介 与C语言相比要注意的地方 objective-c高级特性 开发工具介绍(cocoa 工具包的功能,框架,源文件组织:XCode使用介绍) ...

  7. pthread多线程编程的学习小结

    pthread多线程编程的学习小结  pthread 同步3种方法: 1 mutex 2 条件变量 3 读写锁:支持多个线程同时读,或者一个线程写     程序员必上的开发者服务平台 —— DevSt ...

  8. ExtJs学习笔记之学习小结LoginDemo

    ExtJs学习小结LoginDemo 1.示例:(登录界面) <!DOCTYPE html> <html> <head> <meta charset=&quo ...

  9. 点滴的积累---J2SE学习小结

    点滴的积累---J2SE学习小结 什么是J2SE J2SE就是Java2的标准版,主要用于桌面应用软件的编程:包括那些构成Java语言核心的类.比方:数据库连接.接口定义.输入/输出.网络编程. 学习 ...

随机推荐

  1. 搭建Dubbo Admin(五)

    Dubbo Admin下载地址(2019年9月8日):https://github.com/apache/dubbo-admin 注意:JDK要求1.8以上 1. 进入到模块 dubbo-admin- ...

  2. BOI 2003 团伙

    洛谷 P1892 [BOI2003]团伙 洛谷传送门 题目描述 1920年的芝加哥,出现了一群强盗.如果两个强盗遇上了,那么他们要么是朋友,要么是敌人.而且有一点是肯定的,就是: 我朋友的朋友是我的朋 ...

  3. Mybatis中的@Param注解(自己没试过)

    @Param是MyBatis所提供的(org.apache.ibatis.annotations.Param),作为Dao层的注解,作用是用于传递参数,从而可以与SQL中的的字段名相对应//https ...

  4. python 面试真题

    0.Python是什么? Python是一种解释型语言.但是跟C和C的衍生语言不同,Python代码在运行之前不需要编译.其他解释型语言还包括PHP和Ruby. Python是动态类型语言,指的是在声 ...

  5. 部署ComsenzDiscuz BBS论坛系统

    1.准备环节 [root@localhost ~]# unzip ComsenzDiscuz-DiscuzX-master.zip //解包 [root@localhost ~]# cd Discuz ...

  6. cf1039D 分块

    cf1039D 链接 cf 思路 一次k可以贪心O(n)算. 对于\(≤\sqrt{n}\)的k,暴力算. 对于\(>\sqrt{n}\)的k,最多会有\(\sqrt{n}\)种答案,而且答案单 ...

  7. [LeetCode] 221. Maximal Square 最大正方形

    Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and ret ...

  8. springcloud(五,多个服务注册中心eureka)

    spring cloud (一.服务注册demo_eureka) spring cloud (二.服务注册安全demo_eureka) spring cloud (三.服务提供者demo_provid ...

  9. spring boot打包为war包,引入外部jar包

    1,在src/main/resource下新建目录jar,将外部jar包放在该目录下 2,在pom.xml中添加依赖 groupId,artifactId,version可随便写 <depend ...

  10. [Powershell]发布基于.NET Framework的WebAPI和Job控制台程序项目

    获取要发布的定时计划任务. 禁用和停止定时计划任务. 批量强制结束Job进程. 打印定时计划任务状态. 备份项目文件夹. 发布项目文件夹. 删除部署包. 启用定时计划任务. <# .NOTES ...