鼠标区域是一个不可见的项目,通常与可见项目一起使用,以便为该项目提供鼠标处理。通过有效地充当代理,鼠标处理逻辑可以包含在MouseArea项中。
有关MouseArea和按钮单击的信息是通过为其定义事件处理程序属性的信号提供的。最常用的是处理鼠标的按下和点击:onClicked, onDoubleClicked, onPressed, onReleased 和 onPressAndHold。也可以通过onWheel信号处理鼠标滚轮事件。
如果一个MouseArea 与其他鼠标区域项目的区域重叠,可以通过将propagateComposedEvents设置为true并拒绝应该传播的事件,选择将单击、双击和按下按住事件传播到这些其他项目。
以下讲解,均在Window部件中进行!
Window {id: rootvisible: truewidth: 400height: 500title: qsTr("Hello World")color: "white"//MouseArea { }
}
1.鼠标按下事件
onClicked 鼠标按下然后松开触发
onDoubleClicked 鼠标双击触发
onPressed 鼠标按下触发
onReleased 鼠标松开触发
MouseArea {id: mouseAreawidth: 200height: 200// 为了让鼠标区域显示出来Rectangle {anchors.fill: parentcolor: "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: mouseAreawidth: 200height: 200// 设置监听鼠标的左键和右键acceptedButtons: Qt.LeftButton | Qt.RightButton// 为了让鼠标区域显示出来Rectangle {anchors.fill: parentcolor: "gray"}onPressed: {//console.log("pressed");// pressedButtons & 按钮枚举 - 可知道是哪个按下var left = pressedButtons & Qt.LeftButtonvar right = pressedButtons & Qt.RightButtonconsole.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: mouseAreawidth: 200height: 200// 为了让鼠标区域显示出来Rectangle {anchors.fill: parentcolor: "gray"}// 鼠标长按时触发pressAndHoldInterval: 2000onPressAndHold: {console.log("长按...")}
}
2.鼠标悬浮
鼠标悬浮,即鼠标指针悬浮在鼠标区域内,所触发的一些操作;
将 hoverEnabled 属性设置为true,即可启动鼠标悬浮;
除了上面说的onContainsMouseChanged: { } 会触发后,还有什么会触发吗?
有的,其本身也会触发一个槽函数 onHoveredChanged: { } ;
MouseArea {id: mouseAreawidth: 200height: 200// 为了让鼠标区域显示出来Rectangle {anchors.fill: parentcolor: "gray"}// 设置监听鼠标的左键和右键acceptedButtons: Qt.LeftButton | Qt.RightButton// 启动悬浮hoverEnabled: trueonHoveredChanged: {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帮助手册。
完!