Problem with MouseArea in delegate
-
Hi everybody!
I have a repeater which inserts rectangles in a GridLayout (see below), each rectangle holding a MouseArea. I want to catch the following mouse events:
1.) The user clicks one of the rectangles and keeps the mouse button pressed.
--> catch onPressed
2.) The user moves the mouse around, still pressing the button
--> catch onEntered from every rectangle the mouse pointer enters
3.) The user releases the mouse button
--> catch onReleasedSomehow I am not able to implement this. If I set mouse.accepted = false in my onPressed-handler, I get the following onEntered-events, but never a onReleased. If I do mouse.accepted = true in onPressed, I get a final onRelaesed-event, but never a onEntered.
I tried to put another MouseArea in front or behind the GridLayout, but nothing seems to work. Google was no help, either. Could anybody point me in the right direction?Thanks
P.S.: My code:
GridLayout { id: fieldGrid anchors.fill:parent //... Repeater { id: repeater model: game.board // My delegate Rectangle { id: del // coord comes from model Layout.column: coord.x Layout.row: coord.y Layout.fillWidth: true Layout.fillHeight: true //... MouseArea { id: delMouseArea anchors.fill: parent acceptedButtons: Qt.LeftButton hoverEnabled: true onPressed: { console.log("onPressed") mouse.accepted = false; } onReleased: { console.log("onReleased") } onEntered: { console.log("onEntered") } } } } }
-
Hi everybody!
I have a repeater which inserts rectangles in a GridLayout (see below), each rectangle holding a MouseArea. I want to catch the following mouse events:
1.) The user clicks one of the rectangles and keeps the mouse button pressed.
--> catch onPressed
2.) The user moves the mouse around, still pressing the button
--> catch onEntered from every rectangle the mouse pointer enters
3.) The user releases the mouse button
--> catch onReleasedSomehow I am not able to implement this. If I set mouse.accepted = false in my onPressed-handler, I get the following onEntered-events, but never a onReleased. If I do mouse.accepted = true in onPressed, I get a final onRelaesed-event, but never a onEntered.
I tried to put another MouseArea in front or behind the GridLayout, but nothing seems to work. Google was no help, either. Could anybody point me in the right direction?Thanks
P.S.: My code:
GridLayout { id: fieldGrid anchors.fill:parent //... Repeater { id: repeater model: game.board // My delegate Rectangle { id: del // coord comes from model Layout.column: coord.x Layout.row: coord.y Layout.fillWidth: true Layout.fillHeight: true //... MouseArea { id: delMouseArea anchors.fill: parent acceptedButtons: Qt.LeftButton hoverEnabled: true onPressed: { console.log("onPressed") mouse.accepted = false; } onReleased: { console.log("onReleased") } onEntered: { console.log("onEntered") } } } } }
Hi @nnnnn and Welcome,
PuttingGridLayout
insideMouseArea
should work. In that case addonReleased
event handler for thatMouseArea
. Now once this event is triggered you just have to find the child ofGridLayout
under that mouse location. Like this:MouseArea { anchors.fill:parent onReleased: console.log(fieldGrid.childAt(mouseX,mouseY).objectName) GridLayout { id: fieldGrid ... ...
This will print the object name of the
Rectangle
under that mouse location.The problem why we need to do this is because that event do not work if area moves under the mouse.
-
This is also working for me:
GridView { id: grid clip:true anchors.fill: parent cellWidth: Units.dp(80) cellHeight: Units.dp(80) interactive: false delegate: Rectangle { id: rect width: grid.cellWidth - Units.dp(5) height: grid.cellHeight - Units.dp(5) color: backcolor MouseArea { hoverEnabled: true anchors.fill: parent onPressed: { console.log("pressed") } onReleased: { console.log("released") } onEntered: { console.log("entered"); } } } Component.onCompleted: { for(var i=0;i<36;i++) { grid.model.append({backcolor: "#E0E0E0"}); } } model: ListModel { } }
-
Thanks for your answer!
Unfortunately, this did not solve my problem. With an additional MouseArea (as parent of the GridLayout) I can capture the Released-events (form the outer MouseArea), the Pressed-event (from the inner MouseAreas), however I do not see any Entered-events anymore :-(
-
Thanks for your answer!
Unfortunately, this did not solve my problem. With an additional MouseArea (as parent of the GridLayout) I can capture the Released-events (form the outer MouseArea), the Pressed-event (from the inner MouseAreas), however I do not see any Entered-events anymore :-(
-
Thanks for your answer!
Unfortunately, this did not solve my problem. With an additional MouseArea (as parent of the GridLayout) I can capture the Released-events (form the outer MouseArea), the Pressed-event (from the inner MouseAreas), however I do not see any Entered-events anymore :-(
I tried your example here - I do not get entered-Events when I move the mouse pointer around while the button is pressed; same problem as in my code.
Once again my scenario - to avoid misunderstandings:
Go to a cell, press the button, keep button pressed, move the pointer to other cells, release the button.
In this case, I would like a pressed-event from the first cell, entered-events from all others, and a released-event from the last one. Seems to be tricky...Cheers
-
Hi!
Here is a complete example (which is unfortunately not doing what I want). Anything wrong here?
import QtQuick 2.4 import QtQuick.Window 2.2 import QtQuick.Layouts 1.1 Window { visible: true color: "black" MouseArea { id: outer anchors.fill: parent onReleased: { console.log("outer - onReleased") } GridLayout { id: fieldGrid anchors.fill:parent rows: 2 columns: 2 Repeater { id: repeater model: myModel Rectangle { id: del Layout.column: col Layout.row: row Layout.fillWidth: true Layout.fillHeight: true Text { anchors.centerIn: parent text: name } MouseArea { id: inner anchors.fill: parent hoverEnabled: true onPressed: { console.log("inner - onPressed") mouse.accepted = false; } onEntered: { console.log("inner - onEntered") } } } } } } ListModel { id: myModel ListElement { row: 0; col: 0; name: "a"} ListElement { row: 0; col: 1; name: "b"} ListElement { row: 1; col: 0; name: "c"} ListElement { row: 1; col: 1; name: "d"} } }
-
Hi!
Here is a complete example (which is unfortunately not doing what I want). Anything wrong here?
import QtQuick 2.4 import QtQuick.Window 2.2 import QtQuick.Layouts 1.1 Window { visible: true color: "black" MouseArea { id: outer anchors.fill: parent onReleased: { console.log("outer - onReleased") } GridLayout { id: fieldGrid anchors.fill:parent rows: 2 columns: 2 Repeater { id: repeater model: myModel Rectangle { id: del Layout.column: col Layout.row: row Layout.fillWidth: true Layout.fillHeight: true Text { anchors.centerIn: parent text: name } MouseArea { id: inner anchors.fill: parent hoverEnabled: true onPressed: { console.log("inner - onPressed") mouse.accepted = false; } onEntered: { console.log("inner - onEntered") } } } } } } ListModel { id: myModel ListElement { row: 0; col: 0; name: "a"} ListElement { row: 0; col: 1; name: "b"} ListElement { row: 1; col: 0; name: "c"} ListElement { row: 1; col: 1; name: "d"} } }
-
I have a simple solution now, using only one MouseArea on top and looking for onPositionChanged. I don't think it is very beautifuly (I have to call childAt() all the time), but at least it is working.
import QtQuick 2.4 import QtQuick.Window 2.2 import QtQuick.Layouts 1.1 Window { visible: true color: "black" GridLayout { id: fieldGrid anchors.fill: parent rows: 2 columns: 2 Repeater { id: repeater model: myModel Rectangle { id: del Layout.column: col Layout.row: row Layout.fillWidth: true Layout.fillHeight: true Text { anchors.centerIn: parent text: name } } } } MouseArea { anchors.fill: parent property point pos: Qt.point(-1, -1) onPressed: { var obj = fieldGrid.childAt(mouse.x, mouse.y) if ( !obj ) return; console.log("onPressed") pos = Qt.point(obj.Layout.row, obj.Layout.column) console.log("newField: " + pos) } onReleased: { console.log("onReleased") } onPositionChanged: { var obj = fieldGrid.childAt(mouse.x, mouse.y) if ( !obj ) return; var newPos = Qt.point(obj.Layout.row, obj.Layout.column) if ( newPos === pos ) return; console.log("newField: " + newPos) pos = newPos; } } ListModel { id: myModel ListElement {row: 0; col: 0; name: "a" } ListElement {row: 0; col: 1; name: "b" } ListElement {row: 1; col: 0; name: "c" } ListElement {row: 1; col: 1; name: "d" } } }
-
I have a simple solution now, using only one MouseArea on top and looking for onPositionChanged. I don't think it is very beautifuly (I have to call childAt() all the time), but at least it is working.
import QtQuick 2.4 import QtQuick.Window 2.2 import QtQuick.Layouts 1.1 Window { visible: true color: "black" GridLayout { id: fieldGrid anchors.fill: parent rows: 2 columns: 2 Repeater { id: repeater model: myModel Rectangle { id: del Layout.column: col Layout.row: row Layout.fillWidth: true Layout.fillHeight: true Text { anchors.centerIn: parent text: name } } } } MouseArea { anchors.fill: parent property point pos: Qt.point(-1, -1) onPressed: { var obj = fieldGrid.childAt(mouse.x, mouse.y) if ( !obj ) return; console.log("onPressed") pos = Qt.point(obj.Layout.row, obj.Layout.column) console.log("newField: " + pos) } onReleased: { console.log("onReleased") } onPositionChanged: { var obj = fieldGrid.childAt(mouse.x, mouse.y) if ( !obj ) return; var newPos = Qt.point(obj.Layout.row, obj.Layout.column) if ( newPos === pos ) return; console.log("newField: " + newPos) pos = newPos; } } ListModel { id: myModel ListElement {row: 0; col: 0; name: "a" } ListElement {row: 0; col: 1; name: "b" } ListElement {row: 1; col: 0; name: "c" } ListElement {row: 1; col: 1; name: "d" } } }