QML MouseArea 鼠标事件详解

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

有关MouseArea和按钮单击的信息是通过为其定义事件处理程序属性的信号提供的。最常用的是处理鼠标的按下和点击:onClicked, onDoubleClicked, onPressed, onReleased 和 onPressAndHold。也可以通过onWheel信号处理鼠标滚轮事件。

如果一个MouseArea 与其他鼠标区域项目的区域重叠,可以通过将propagateComposedEvents设置为true并拒绝应该传播的事件,选择将单击、双击和按下按住事件传播到这些其他项目。

以下讲解,均在Window部件中进行!

Window {
    id: root
    visible: true
    width: 400
    height: 500
    title: qsTr("Hello World")
    color: "white"

    //MouseArea { }
}

1.鼠标按下事件

onClicked                鼠标按下然后松开触发

onDoubleClicked        鼠标双击触发

onPressed                鼠标按下触发

onReleased                鼠标松开触发

MouseArea {
    id: mouseArea
    width: 200
    height: 200

    // 为了让鼠标区域显示出来
    Rectangle {
        anchors.fill: parent
        color: "gray"
    }

    onClicked:  {
        console.log("clicked");
    }
    onDoubleClicked: {
        console.log("double clicked")
    }

    onPressed:  {
        console.log("pressed");
    }
    onReleased: {
        console.log("release")
    }
}

1).如何区分是左键按下还是右键按下?

使用 pressedButtons 属性可用于区分;

另外,还需要用到 acceptedButtons 属性acceptedButtons: Qt.LeftButton | Qt.RightButton 还需监听左和右;

之后,就可以在onPressed槽函数中,pressedButtons属性和 Qt.LeftButton 或者 Qt.RightButton 做 & 操作,得出数值;

如果 pressedButtons & Qt.LeftButton 为1,那么就是左键按下;

如果 pressedButtons & Qt.RightButton 为2,那么就是右键按下;

  MouseArea {
    id: mouseArea
    width: 200
    height: 200

    // 设置监听鼠标的左键和右键
    acceptedButtons: Qt.LeftButton | Qt.RightButton

    // 为了让鼠标区域显示出来
    Rectangle {
        anchors.fill: parent
        color: "gray"
    }


    onPressed:  {
        //console.log("pressed");

        // pressedButtons & 按钮枚举   - 可知道是哪个按下
        var left = pressedButtons & Qt.LeftButton
        var right = pressedButtons & Qt.RightButton
        console.log("left:", left, "  right", right)

        if (1 == left) {
            console.log("mouse left pressed.")
        } else if (2 == right) {
            console.log("mouse right pressed.")
        } else {
            console.log("other pressed.")
        }
    }
    onReleased: {
        console.log("release")
    }
}

打印0表示没按下!

onContainsPressChanged: { } onContainsMouseChanged: { }

槽函数也可以处理鼠标按下;

不过其有点特殊,鼠标按下时会触发,松开后也会触发一次;

onContainsMouseChanged: {                         
    console.log("containsMouse", containsMouse)   
}                                                 
                                                  
onContainsPressChanged: {                         
    console.log("containsPress", containsPress)                                             
}                                          

按下时,值为true,松开后,值为false;

当然,在 onContainsPressChanged: { } 内,也可以使用 pressedButtons 属性去判断鼠标左键还是右键按下!

onContainsMouseChanged: { } 却不可以!

不过,onContainsMouseChanged: { } 可以和鼠标悬浮一起使用!

当启动鼠标悬浮后,鼠标指针进入鼠标区域,即可触发onContainsMouseChanged: { }

2).鼠标长按

onPressAndHold: { } 槽函数可以在鼠标长按时执行;

可通过 pressAndHoldInterval 属性去设置长按的时间;

MouseArea {
    id: mouseArea
    width: 200
    height: 200
    // 为了让鼠标区域显示出来
    Rectangle {
        anchors.fill: parent
        color: "gray"
    }


    // 鼠标长按时触发
    pressAndHoldInterval: 2000

    onPressAndHold: {
        console.log("长按...")
    }
}

2.鼠标悬浮

鼠标悬浮,即鼠标指针悬浮在鼠标区域内,所触发的一些操作;

将 hoverEnabled 属性设置为true,即可启动鼠标悬浮;

除了上面说的onContainsMouseChanged: { } 会触发后,还有什么会触发吗?

有的,其本身也会触发一个槽函数 onHoveredChanged: { } ;

MouseArea {
    id: mouseArea
    width: 200
    height: 200
    // 为了让鼠标区域显示出来
    Rectangle {
        anchors.fill: parent
        color: "gray"
    }

    // 设置监听鼠标的左键和右键
    acceptedButtons: Qt.LeftButton | Qt.RightButton

    // 启动悬浮
    hoverEnabled: true
    onHoveredChanged: {
        console.log("onHoveredChanged")
    }
    // 只有hoverEnabled设置为true时,onContainsMouseChanged在鼠标悬浮时会触发;否则只有鼠标按下时才会触发
    onContainsMouseChanged: {
        console.log("containsMouse", containsMouse)
    }
}

另外,可以通过 cursorShape 属性改变悬浮时鼠标的指针;

// 当启动悬浮后,可设置悬浮时鼠标指针            
cursorShape: Qt.ClosedHandCursor

更多请查看帮助文档的 Qt::CursorShape 枚举;

3.鼠标按下拖动

使用 drag 属性,可以通过鼠标拖动部件;

其中需要设置几个重要的属性;

drag.target         目标id
drag.axis          移动方向,可以是 (Drag.XAxis), (Drag.YAxis), or both (Drag.XAndYAxis)
drag.minimum 和 drag.maximum  最大值xy和最小是xy;

Rectangle {                                                                             
    id: rect                                                                            
    width: 50; height: 50                                                               
    color: "red"                                                                        
    // 越往右边,透明度越小                                                                       
    //opacity: (root.width - rect.x) / root.width                                       
                                                                                        
    MouseArea {                                                                         
        anchors.fill: parent                                                            
                                                                                        
        // drag 提供了一种方便的方法来使项目可拖动                                                       
        drag.target: rect                                                               
        // 移动方向                                                                         
        drag.axis: Drag.XAndYAxis   // Drag.XAxis or Drag.YAxis or both Drag.XAndYAxis  
                                                                                        
        // 设置移动的范围                                                                      
        drag.minimumX: 0                                                                
        drag.maximumX: root.width - rect.width                                          
        drag.minimumY: 0                                                                
        drag.maximumY: root.height - rect.height                                        
    }
}          

drag 的 filterChildren 属性,如果设置为false,其子部件点击是不可以拖动的,例如:
Rectangle {                                        
    id: rect                                       
    x: 30; y: 30                                   
    width: 300; height: 240                        
    color: "lightsteelblue"                        
                                                   
    MouseArea {                                    
      anchors.fill: parent                         
      drag.target: rect;                           
      drag.axis: Drag.XAxis | Drag.YAxis           
      drag.minimumX: 0                             
      drag.maximumX: root.width - rect.width       
      drag.minimumY: 0                             
      drag.maximumY: root.height - rect.height     
                                                   
      // 如果为true,点击子部件可以拖动;false则不行                
      drag.filterChildren: true                    
                                                   
      Rectangle {                                  
          color: "yellow"                          
          x: 50; y : 50                            
          width: 100; height: 100                  
          MouseArea {                              
              anchors.fill: parent                 
              onClicked: console.log("Clicked")    
          }                                        
      }                                            
    }                                              
}                                               

4.鼠标点击事件穿透

还有一个比较有意思的就是,

有一个矩形1,其内部也还有一个矩形2,当我们点击矩形1的时候,打印矩形1,当我们点击矩形2的时候,打印矩形2;

那么请问,如果我想在点击矩形2的时候,也会触发矩形1的打印,这该如何实现呢?

可以设置  mouse.accepted = false

和设置 propagateComposedEvents: true

即可实现!

Rectangle {                                       
    color: "yellow"                               
    width: 100; height: 100                       
                                                  
    MouseArea {                                   
        anchors.fill: parent                      
        onClicked: console.log("clicked yellow")  
    }                                             
                                                  
    Rectangle {                                   
        color: "blue"                             
        width: 50; height: 50                     
                                                  
        MouseArea {                               
            anchors.fill: parent                  
            propagateComposedEvents: true       
            onClicked: {                          
                console.log("clicked blue")       
                mouse.accepted = false          
            }                                     
        }                                         
    }                                             
}              

5.总结

一般来说,鼠标事件,最常用的就是按下事件了,一般都是按下后做一些处理操作,只需要掌握之一部分内容就基本可以了;

其余用法现在有个影响,等到实际项目遇到时,再翻看一下qt帮助手册。

完!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cpp_learners

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值