У меня есть несколько родственных элементов Rectangle со свойством radius, поэтому они отображаются в виде кругов.Каждый из них имеет дочерний элемент, имеющий дочернюю мышь MouseArea, цель элемента заключается в реализации эффекта «круглой области мыши» ( оригинальный ответ SO ).Item и MouseArea оснащены такими инструментами, что щелчки и перетаскивания будут действовать только в пределах видимой круглой формы прямоугольника, а не в пределах ограничивающей рамки, которая является реальной площадью прямоугольника.ниже.При перетаскивании по точке желаемый результат - движение круга 1, и это происходит в большинстве случаев.Однако этого не происходит, когда вы создаете круг 1, затем круг 2, а затем перемещаете курсор мыши на точку.Если вы сделаете это и попытаетесь перетащить или щелкнуть, ваше взаимодействие переместится в фоновое полноэкранное MouseArea и создаст новый круг.
Причиной этой проблемы является то, что когда курсор мыши перемещается к точке из круга # 2, mouseArea и mouseY для круга # 1 MouseArea не обновляются.Когда круг № 2 позволяет щелчку распространяться вниз, он попадает в прямоугольник круга № 1, но затем элемент № 1 круга утверждает, что содержит значение «false» и снова распространяется вниз.
Как только курсор мыши покидает следограничивающего прямоугольника круга # 2, например, немного переместившись вверх или влево от точки, MouseArea круга # 1 обновляется, и его containsMouse становится истинным, и он начинает захватывать щелчки и перетаскивать.
Я пробовалГорстка потенциальных решений и не намного дальше, чем приведенный ниже код.
import QtQuick 2.12
import QtQuick.Controls 2.5
ApplicationWindow {
visible: true
width: 640
height: 480
property real spotlightRadius: 100
MouseArea {
visible: true
anchors.fill: parent
onClicked: {
spotlightComponent.createObject(parent, {
"x": x + mouseX - spotlightRadius,
"y": y + mouseY - spotlightRadius,
"width": spotlightRadius * 2,
"height": spotlightRadius * 2
})
}
}
Component {
id: spotlightComponent
Rectangle {
id: spotlightCircle
visible: true
x: parent.x
y: parent.y
width: parent.width
height: parent.height
radius: Math.max(parent.width, parent.height) / 2
color: Qt.rgba(Math.random()*0.5+0.5,Math.random()*0.5+0.5,Math.random()*0.5+0.5,0.5);
Item {
anchors.fill: parent
drag.target: parent
onDoubleclicked: parent.destroy()
onWheel: { parent.z += wheel.pixelDelta.y; currentSpotlight = parent }
property alias drag: mouseArea.drag
//FIXME when moving the mouse out of a higher element's containsMouse circle
// but still inside its mouseArea.containsMouse square, lower elements'
// mouseArea do not update, so their containsMouse doesn't update, so clicks
// fall through when they should not.
property bool containsMouse: {
var x1 = width / 2;
var y1 = height / 2;
var x2 = mouseArea.mouseX;
var y2 = mouseArea.mouseY;
var deltax = x1 - x2;
var deltay = y1 - y2;
var distance2 = deltax * deltax + deltay * deltay;
var radius2 = Math.pow(Math.min(width, height) / 2, 2);
return distance2 < radius2;
}
signal clicked(var mouse)
signal doubleclicked(var mouse)
signal wheel(var wheel)
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
//FIXME without acceptedButtons, propagated un-accepted clicks end up with the wrong coordinates
acceptedButtons: parent.containsMouse ? Qt.LeftButton : Qt.NoButton
propagateComposedEvents: true
onClicked: { if (parent.containsMouse) { parent.clicked(mouse) } else { mouse.accepted = false } }
onDoubleClicked: { if (parent.containsMouse) { parent.doubleclicked(mouse) } }
onWheel: { if (parent.containsMouse) { parent.wheel(wheel) } }
drag.filterChildren: true
}
}
}
}
}