zoukankan      html  css  js  c++  java
  • QML MouseArea学习小结

    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
     
    import QtQuick 2.12
    import QtQuick.Window 2.12

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

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

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

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

            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
     
    import QtQuick 2.0

    Item {
        id: roundMouseArea

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

        property bool containsMouse: {
            
    var x1 = width / 2;
            
    var y1 = height / 2;
            
    var x2 = mouseX;
            
    var y2 = mouseY;
            
    var distanceFromCenter = Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2);
            
    var radiusSquared = Math.pow(Math.min(width, height) / 22);
            
    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 : 100
        height : 
    100
        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 / 
    2
            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();

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

        qreal r = qBound<
    int>(0, m_alphaThreshold * 255255);
        
    //根据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 ? 1.1 : 1.0
        opacity : moonArea.containsMouse ? 
    1.0 : 0.7
        source : Qt.resolvedUrl(
    "images/moon.png")

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

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

    gif走起来:

  • 相关阅读:
    SpringBoot中mybatis配置自动转换驼峰标识没有生效
    mybatis-plus-扩展使用
    myabtis-plus使用
    mybatis-plus特性
    Mariadb Galera Cluster 故障快速拉起
    galera集群启动异常问题汇总
    Galera Cluster grastate.dat文件详解
    mongodb配置文件详解
    wsrep配置一览
    MySQL Galera cluster集群常用参数说明
  • 原文地址:https://www.cnblogs.com/MakeView660/p/11238608.html
Copyright © 2011-2022 走看看