如何让double MouseArea生效?
How to make double MouseArea take effect?
这是我的 QML 代码:
Rectangle
{
.....
Rectangle
{
....height and width is smaller than parent
MouseArea
{
id: mouseArea2
anchors.fill: parent
hoverEnabled: true
onEntered:
{
console.log("enter 2")
}
}
}
MouseArea
{
id: mouseArea1
anchors.fill: parent
hoverEnabled: true
onEntered:
{
console.log("enter 1")
}
}
}
只有mouseArea1
生效。如果我删除 mouseArea1
然后 mouseArea2
生效。所以我认为鼠标事件必须由mouseArea1
处理,不能传递给mouseArea2
。
我搜索文档以找出哪个 attr 可以防止此类行为,但没有找到。那么如何让mouseArea1
和mouseArea2
同时生效呢?
我在文档中找到了解决方案。以下面的 QML 代码为例:
import QtQuick 2.0
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
}
}
}
}
此处黄色 Rectangle
包含一个蓝色矩形。后者是视觉堆叠顺序层次结构中最顶层的项目;它将在视觉上呈现在前者之上。
由于蓝色Rectangle
将propagateComposedEvents
设置为true
,并将所有收到的点击事件设置为MouseEvent::accepted
至false
,任何点击事件它receives 被传播到它下面黄色矩形的 MouseArea
。
单击蓝色 Rectangle
将调用其子 MouseArea
的 onClicked
处理程序;然后事件将传播到黄色 Rectangle
的 MouseArea
,导致调用其自己的 onClicked
处理程序。
对于 "composed" 鼠标事件 -- clicked
、doubleClicked
和 pressAndHold
-- 您可以使用 propagateComposedEvents
属性 .但这在这里行不通,因为悬停事件不是组合事件。
所以您需要做的是更改评估 MouseArea
的顺序。
一个简单的技巧是交换 QML 源本身中两个 MouseArea
的顺序。通过将较小的放在较大的之后,较小的优先:
Rectangle{
//.....
MouseArea{
id: mouseArea1
anchors.fill: parent
hoverEnabled: true
onEntered:{
console.log("enter 1")
}
}
Rectangle{
//....height and width is smaller than parent
MouseArea{
id: mouseArea2
anchors.fill: parent
hoverEnabled: true
onEntered:{
console.log("enter 2")
}
}
}
}
实现相同目的的第二种方法是将 z
索引添加到大于较低索引的最顶端 MouseArea
。默认情况下,每个元素都有一个 0
的 z
索引,因此只需将 z: 1
添加到较小的 MouseArea
即可:
Rectangle{
//.....
Rectangle{
//....height and width is smaller than parent
MouseArea{
z: 1 // <-----------------
id: mouseArea2
anchors.fill: parent
hoverEnabled: true
onEntered:{
console.log("enter 2")
}
}
}
MouseArea{
id: mouseArea1
anchors.fill: parent
hoverEnabled: true
onEntered:{
console.log("enter 1")
}
}
}
这是我的 QML 代码:
Rectangle
{
.....
Rectangle
{
....height and width is smaller than parent
MouseArea
{
id: mouseArea2
anchors.fill: parent
hoverEnabled: true
onEntered:
{
console.log("enter 2")
}
}
}
MouseArea
{
id: mouseArea1
anchors.fill: parent
hoverEnabled: true
onEntered:
{
console.log("enter 1")
}
}
}
只有mouseArea1
生效。如果我删除 mouseArea1
然后 mouseArea2
生效。所以我认为鼠标事件必须由mouseArea1
处理,不能传递给mouseArea2
。
我搜索文档以找出哪个 attr 可以防止此类行为,但没有找到。那么如何让mouseArea1
和mouseArea2
同时生效呢?
我在文档中找到了解决方案。以下面的 QML 代码为例:
import QtQuick 2.0
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
}
}
}
}
此处黄色 Rectangle
包含一个蓝色矩形。后者是视觉堆叠顺序层次结构中最顶层的项目;它将在视觉上呈现在前者之上。
由于蓝色Rectangle
将propagateComposedEvents
设置为true
,并将所有收到的点击事件设置为MouseEvent::accepted
至false
,任何点击事件它receives 被传播到它下面黄色矩形的 MouseArea
。
单击蓝色 Rectangle
将调用其子 MouseArea
的 onClicked
处理程序;然后事件将传播到黄色 Rectangle
的 MouseArea
,导致调用其自己的 onClicked
处理程序。
对于 "composed" 鼠标事件 -- clicked
、doubleClicked
和 pressAndHold
-- 您可以使用 propagateComposedEvents
属性 .但这在这里行不通,因为悬停事件不是组合事件。
所以您需要做的是更改评估 MouseArea
的顺序。
一个简单的技巧是交换 QML 源本身中两个 MouseArea
的顺序。通过将较小的放在较大的之后,较小的优先:
Rectangle{
//.....
MouseArea{
id: mouseArea1
anchors.fill: parent
hoverEnabled: true
onEntered:{
console.log("enter 1")
}
}
Rectangle{
//....height and width is smaller than parent
MouseArea{
id: mouseArea2
anchors.fill: parent
hoverEnabled: true
onEntered:{
console.log("enter 2")
}
}
}
}
实现相同目的的第二种方法是将 z
索引添加到大于较低索引的最顶端 MouseArea
。默认情况下,每个元素都有一个 0
的 z
索引,因此只需将 z: 1
添加到较小的 MouseArea
即可:
Rectangle{
//.....
Rectangle{
//....height and width is smaller than parent
MouseArea{
z: 1 // <-----------------
id: mouseArea2
anchors.fill: parent
hoverEnabled: true
onEntered:{
console.log("enter 2")
}
}
}
MouseArea{
id: mouseArea1
anchors.fill: parent
hoverEnabled: true
onEntered:{
console.log("enter 1")
}
}
}