Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Problem with MouseArea in delegate
QtWS25 Last Chance

Problem with MouseArea in delegate

Scheduled Pinned Locked Moved Solved QML and Qt Quick
mousearea
14 Posts 3 Posters 7.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    nnnnn
    wrote on last edited by A Former User
    #1

    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 onReleased

    Somehow 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")
                    }
                }
            }
        }
    }
    
    
    p3c0P 1 Reply Last reply
    0
    • N nnnnn

      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 onReleased

      Somehow 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")
                      }
                  }
              }
          }
      }
      
      
      p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by
      #2

      Hi @nnnnn and Welcome,
      Putting GridLayout inside MouseArea should work. In that case add onReleased event handler for that MouseArea. Now once this event is triggered you just have to find the child of GridLayout 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.

      157

      1 Reply Last reply
      0
      • S Offline
        S Offline
        sk2212
        wrote on last edited by
        #3

        @nnnnn

        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 {
        
                        }
           }
        
        1 Reply Last reply
        0
        • N Offline
          N Offline
          nnnnn
          wrote on last edited by
          #4

          @p3c0

          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 :-(

          p3c0P N 2 Replies Last reply
          0
          • N nnnnn

            @p3c0

            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 :-(

            p3c0P Offline
            p3c0P Offline
            p3c0
            Moderators
            wrote on last edited by
            #5

            @nnnnn That's strange. Is there any other component present apart from the code that you posted earlier ?

            157

            1 Reply Last reply
            0
            • N nnnnn

              @p3c0

              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 :-(

              N Offline
              N Offline
              nnnnn
              wrote on last edited by
              #6

              @sk2212

              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

              1 Reply Last reply
              0
              • N Offline
                N Offline
                nnnnn
                wrote on last edited by
                #7

                @p3c0

                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"}
                    }
                }
                
                
                p3c0P 1 Reply Last reply
                0
                • N nnnnn

                  @p3c0

                  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"}
                      }
                  }
                  
                  
                  p3c0P Offline
                  p3c0P Offline
                  p3c0
                  Moderators
                  wrote on last edited by
                  #8

                  @nnnnn This too works on my system. I'm using Qt 5.5 on Ubuntu.

                  157

                  N 1 Reply Last reply
                  0
                  • p3c0P p3c0

                    @nnnnn This too works on my system. I'm using Qt 5.5 on Ubuntu.

                    N Offline
                    N Offline
                    nnnnn
                    wrote on last edited by
                    #9

                    Really? You get Entered-events while you keep the mouse button pressed?

                    Ok, I will check with Qt 5.5 here, I wanted to update anyway. Thanks for your help, I will post how things are going...

                    1 Reply Last reply
                    0
                    • N Offline
                      N Offline
                      nnnnn
                      wrote on last edited by
                      #10

                      Hmm, it's not working for me under Qt5.5/Kubuntu 14.04 either. No entered-Events when I move the mouse around while pressing the mouse button.

                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        sk2212
                        wrote on last edited by
                        #11

                        @nnnnn

                        Ah...got your point. The events are not triggered when you press a button, hold this button and move to another button. THAN the events for the "new" entered button are not triggered.

                        I did not know a solution so far...

                        1 Reply Last reply
                        0
                        • N Offline
                          N Offline
                          nnnnn
                          wrote on last edited by
                          #12

                          I really find no solution for this using MouseArea. My only hope now is that I can find a workaround using a MultiPointTouchArea, but maybe this is something completely different (have to check to documentation first...)

                          1 Reply Last reply
                          0
                          • N Offline
                            N Offline
                            nnnnn
                            wrote on last edited by
                            #13

                            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" }
                                }
                            }
                            
                            
                            p3c0P 1 Reply Last reply
                            0
                            • N nnnnn

                              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" }
                                  }
                              }
                              
                              
                              p3c0P Offline
                              p3c0P Offline
                              p3c0
                              Moderators
                              wrote on last edited by
                              #14

                              @nnnnn Hmm. I overlooked your onEntered requirement. It doesnot work in my example. The problem is that once you set mouse.accepted=false the release event is not trapped.

                              157

                              1 Reply Last reply
                              0

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved