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. vue-cli 3 和 vue-cli 2的区别

    分享文章: 浅谈vue-cli 3 和 vue-cli 2的区别 https://blog.csdn.net/weixin_42080056/article/details/81631661 vue- ...

  2. DRL强化学习:

    IT博客网 热点推荐 推荐博客 编程语言 数据库 前端 IT博客网 > 域名隐私保护 免费 DRL前沿之:Hierarchical Deep Reinforcement Learning 来源: ...

  3. Python进阶-XIII 导入模块和包 异常处理

    一.模块的导入 1).import # 测试一:money与my_module.money不冲突 import my_module money=10 print(my_module.money) '' ...

  4. 在 Asp.Net Core 中安装 MVC

    在 ASP.NET Core 中安装 MVC 到目前为止,我们在本系列视频中使用的 ASP.NET Core 项目是使用“空”项目模板生成的.目前这个项目没有设置和安装 MVC. 两个步骤学会在 AS ...

  5. 洛谷p3385【模板】负环

    最近很久没怎么写最短路的题导致这个题交了好多遍 AC率是怎么下来的自己心里没点数 SPFA虽然臭名昭著但是他可以用来判负环 如果一个点进队的次数大于等于n说明存在负环 这道题一开始memset我给di ...

  6. beeline无密码连接hiveserver2

    1.说明 #hiveserver2增加了权限控制,需要在hadoop的配置文件中配置 core-site.xml 增加以下内容: <property> <name>hadoop ...

  7. c++的CreateFile导致内存不能为written错误

    LPCWSTR szFileName; szFileName=argv[2]; //LPCWSTR szFileName=L"test.txt";//文件名字可以根据自己的需要修改 ...

  8. [LeetCode] 738. Monotone Increasing Digits 单调递增数字

    Given a non-negative integer N, find the largest number that is less than or equal to N with monoton ...

  9. 关于被malloc分配内存的指针

    例如创建了一个链表指针p并为其malloc()分配了内存,那么这个指针指向的地方其实是有数据的. 你可以把p->data打印出来,会发现是一个随机值 因为只是分配内存而没有指定data的值,所以 ...

  10. markdown格式接口文档模板

    源文件 https://files.cnblogs.com/files/bincoding/%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3.zip 目录 测试接口 查询指定项 ...