鼠标区域是一个不可见的项目,通常与可见项目一起使用,以便为该项目提供鼠标处理。通过有效地充当代理,鼠标处理逻辑可以包含在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帮助手册。
完!