How to make MouseArea in Loader take effect?
-
I'm writting a draggable control. This is my minimal reproductive example. My issue is, the hover, click events of
Loader
andMouseArea
cannot take effect at the same time. If I set a biggerz
for either of them, the other will have no effect.Window { id: window width: 400 height: 400 visible: true color: "#181818" Component { id: dele Rectangle { color: "#1f1f1f" Text { anchors.centerIn: parent text: "hello" color: "#cccccc" verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } MouseArea { anchors.fill: parent hoverEnabled: true onClicked: console.log(123) } } } Loader { id: dragTarget width: 200 height: 200 anchors { top: parent.top left: parent.left } sourceComponent: dele Drag.active: mouseArea.drag.active MouseArea { id: mouseArea anchors.fill: parent hoverEnabled: true drag.target: dragTarget onContainsMouseChanged: { console.log(1234) } } states: [ State { when: mouseArea.drag.active AnchorChanges { target: dragTarget anchors { left: undefined top: undefined } } } ] } }
EDIT: I simplified my question. My current problem is that the
MouseArea
inLoader
and theMouseArea
insourceComponent
cannot take effect at the same time. -
Does taking Loader and sourceComponent of the loader out of the picture change the situation?
Getting a clicked() signal out of overlapping MouseArea instances should be a problem regardless. When an event is accepted, it is not passed on to parents or siblings lower on the Z stack. Composed events such as a click (press + release) require the constituent basic events to be accepted by an item.
https://doc.qt.io/qt-6/qml-qtquick-mousearea.html#clicked-signal:
When handling this signal, changing the accepted property of the mouse parameter has no effect, unless the propagateComposedEvents property is true.
https://doc.qt.io/qt-6/qml-qtquick-mouseevent.html#accepted-prop:
_ Setting accepted to true prevents the mouse event from being propagated to items below this item._
Generally, if the item acts on the mouse event then it should be accepted so that items lower in the stacking order do not also respond to the same event.
https://doc.qt.io/qt-6/qml-qtquick-mousearea.html#propagateComposedEvents-prop:
This property holds whether composed mouse events will automatically propagate to other MouseAreas that overlap with this MouseArea but are lower in the visual stacking order. By default, this property is false.
MouseArea contains several composed events: clicked, doubleClicked and pressAndHold. These are composed of basic mouse events, like pressed, and can be propagated differently in comparison to basic events.
If propagateComposedEvents is set to true, then composed events will be automatically propagated to other MouseAreas in the same location in the scene. Each event is propagated to the next enabled MouseArea beneath it in the stacking order, propagating down this visual hierarchy until a MouseArea accepts the event. Unlike pressed events, composed events will not be automatically accepted if no handler is present.
-
Does taking Loader and sourceComponent of the loader out of the picture change the situation?
Getting a clicked() signal out of overlapping MouseArea instances should be a problem regardless. When an event is accepted, it is not passed on to parents or siblings lower on the Z stack. Composed events such as a click (press + release) require the constituent basic events to be accepted by an item.
https://doc.qt.io/qt-6/qml-qtquick-mousearea.html#clicked-signal:
When handling this signal, changing the accepted property of the mouse parameter has no effect, unless the propagateComposedEvents property is true.
https://doc.qt.io/qt-6/qml-qtquick-mouseevent.html#accepted-prop:
_ Setting accepted to true prevents the mouse event from being propagated to items below this item._
Generally, if the item acts on the mouse event then it should be accepted so that items lower in the stacking order do not also respond to the same event.
https://doc.qt.io/qt-6/qml-qtquick-mousearea.html#propagateComposedEvents-prop:
This property holds whether composed mouse events will automatically propagate to other MouseAreas that overlap with this MouseArea but are lower in the visual stacking order. By default, this property is false.
MouseArea contains several composed events: clicked, doubleClicked and pressAndHold. These are composed of basic mouse events, like pressed, and can be propagated differently in comparison to basic events.
If propagateComposedEvents is set to true, then composed events will be automatically propagated to other MouseAreas in the same location in the scene. Each event is propagated to the next enabled MouseArea beneath it in the stacking order, propagating down this visual hierarchy until a MouseArea accepts the event. Unlike pressed events, composed events will not be automatically accepted if no handler is present.
-
What about using TapHandler and DragHandler?
Window { id: window width: 400 height: 400 visible: true color: "#181818" Component { id: dele Rectangle { color: "#1f1f1f" Text { anchors.centerIn: parent text: "hello" color: "#cccccc" verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } TapHandler { onTapped: { console.log("tapped") } } } } Loader { id: dragTarget width: 200 height: 200 sourceComponent: dele DragHandler {} } }
-
What about using TapHandler and DragHandler?
Window { id: window width: 400 height: 400 visible: true color: "#181818" Component { id: dele Rectangle { color: "#1f1f1f" Text { anchors.centerIn: parent text: "hello" color: "#cccccc" verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } TapHandler { onTapped: { console.log("tapped") } } } } Loader { id: dragTarget width: 200 height: 200 sourceComponent: dele DragHandler {} } }