I don't think it's possible to do that, at least from within QML. The green mouse area doesn't have hoverEnabled
set to true, so you won't receive any position changes for it.
A better way of approaching this problem is to use a larger MouseArea
that fills the maximum area you're interested in, and use mapToItem() / mapFromItem() to translate the global mouse position to local coordinates for comparison against each mouse area:
import QtQuick 2.4
import QtQuick.Window 2.2
Window {
id: window
visible: true
width: 200
height: 200
Rectangle {
anchors.fill: parent
color: "yellow"
}
MouseArea {
id: globalMouseArea
anchors.fill: parent
hoverEnabled: true
}
MouseArea {
id: redMouseArea
width: 150
height: 150
cursorShape: containsMouse ? Qt.OpenHandCursor : Qt.ArrowCursor
enabled: false
readonly property bool containsMouse: {
var relativePos = mapFromItem(globalMouseArea, globalMouseArea.mouseX, globalMouseArea.mouseY);
return contains(Qt.point(relativePos.x, relativePos.y));
}
Rectangle {
anchors.fill: parent
color: "red"
}
}
Rectangle {
id: greenMouseArea
x: 50
y: 50
width: 150
height: 150
color: containsMouse ? "brown" : "green"
readonly property bool containsMouse: {
var relativePos = mapFromItem(globalMouseArea, globalMouseArea.mouseX, globalMouseArea.mouseY);
return contains(Qt.point(relativePos.x, relativePos.y));
}
Connections {
target: globalMouseArea
onPressed: if (greenMouseArea.containsMouse) greenMouseArea.pressed()
}
signal pressed
onPressed: console.log("Ahoj!")
}
}
As you can see, the green mouse area is no longer a mouse area. It seems that a mouse area that has a higher stacking order than another mouse area will block position changes for the lower mouse area, even if the higher one doesn't have hoverEnabled
set to true.
Also, note that it would be slightly more concise if it weren't for QTBUG-41452. Namely, you could shorten the containsMouse
expression:
readonly property bool containsMouse: contains(mapFromItem(globalMouseArea, globalMouseArea.mouseX, globalMouseArea.mouseY))
If you're concerned about the code duplication here, then you can use a function instead:
import QtQuick 2.4
import QtQuick.Window 2.2
Window {
id: window
visible: true
width: 200
height: 200
Rectangle {
anchors.fill: parent
color: "yellow"
}
MouseArea {
id: globalMouseArea
anchors.fill: parent
hoverEnabled: true
}
function containsMouse(item) {
var relativePos = globalMouseArea.mapToItem(item, globalMouseArea.mouseX, globalMouseArea.mouseY);
return item.contains(Qt.point(relativePos.x, relativePos.y));
}
MouseArea {
id: redMouseArea
width: 150
height: 150
cursorShape: window.containsMouse(redMouseArea) ? Qt.OpenHandCursor : Qt.ArrowCursor
enabled: false
Rectangle {
anchors.fill: parent
color: "red"
}
}
Rectangle {
id: greenMouseArea
x: 50
y: 50
width: 150
height: 150
color: containsMouse ? "brown" : "green"
readonly property bool containsMouse: window.containsMouse(greenMouseArea)
Connections {
target: globalMouseArea
onPressed: if (greenMouseArea.containsMouse) greenMouseArea.pressed()
}
signal pressed
onPressed: console.log("Ahoj!")
}
}
I used a property for the green mouse area, as it would otherwise call containsMouse()
twice, which is wasteful.