MouseArea stole QML element's mouse events
Asked Answered
D

4

16

If I put a MouseArea on a QML element, then MouseArea will steal all mouse events. Thus, TextEdit will be uneditable and unselectable.

TextEdit {
    // some properties
    MouseArea {
        // some properties
        onClicked: { /* do something */ }
    }
}

Is there a way to solve it?

By the way, if I put a large MouseArea on another MouseArea, larger MouseArea will steal all mouse events. How do I solved it? I think passing on mouse events manually can solve that, but how to do it?

Doiron answered 24/4, 2013 at 4:32 Comment(0)
B
28

You have to enable the MouseArea to propagate the composed events like clicked or released to the underneath component, as described by @Torgeirl's answer.

If you want your TextEdit, Slider or CheckBox to receive these kind of events, simply pass through the event by setting its accepted property to false.

Sample code:

RowLayout {
    TextEdit { text: "Hi" }
    Slider {}
    CheckBox { text: "CheckBox"}

    MouseArea {
        anchors.fill: parent
        propagateComposedEvents: true

        onClicked: mouse.accepted = false;
        onPressed: mouse.accepted = false;
        onReleased: mouse.accepted = false;
        onDoubleClicked: mouse.accepted = false;
        onPositionChanged: mouse.accepted = false;
        onPressAndHold: mouse.accepted = false;
    }
}
Brunei answered 21/4, 2015 at 7:27 Comment(2)
I was looking for a solution to something else when I came across this, and just thought I'd point out that there are some signal handlers for which setting mouse.accepted = false has no effect (search MouseArea docs for has no effect to find them all).Mcmahon
This solution does not work if I want continuous updates on mouseX and mouseY. Change the TextEdit in the example code above to show the mouse X,Y location and you will see it stops updating whenever the mouse button is held down. Setting "mouse.accepted = false" in onPressed causes the MouseArea properties to not be updated until the button is released. Not sure if this is a bug?Autochthon
K
5

There is the property propagateComposedEvents which allows a MouseArea to let through mouse events such as clicked(). You have to set event.accepted = false in the event handler.

Please, see the documentation for MouseArea and the property propagateComposedEvents for more information and example.

Kirkham answered 25/4, 2013 at 18:49 Comment(1)
I use Qt4. I can not use it.Stoddart
M
2

You can try something like this for your particular case:

Rectangle
{
   MouseArea 
   {
      id: mouseAreaTop
      anchors.fill: parent 
      OnClicked: { /* do something */ }
   }

   TextEdit 
   {
      /* Do whatever  */       
   }
}

Note that I have arranged these in an order. All children will have higher z than parent. Siblings coming later in the tree for a parent, have higher z values.

General idea is like this :

  1. Define all the mouse areas
  2. Arrange them on the z values

Read about z property here in the Qt documentation, you will be able to understand how to arrange the mouse areas.

eg:

Parent
{
    anchors.fill: parent
    child1
    {
        anchors.fill: parent
        z: 2
    }

    child2
    {
        anchors.fill: parent
        z: 1
    }

    child3
    {
        anchors.fill: parent
        z: 4
    }

    child4
    {
        anchors.fill: parent
        z: 3
    }
}

In this example i have overridden the natural ordering by assigning the z values myself.

Menorca answered 24/4, 2013 at 13:6 Comment(1)
No. That's isn't what I want. In your first example, mouseEvent will not emit because TextEdit is higher than mouseArea. I want TextEdit accept mouseEvent and selectable at the same time. I want to find a way to simulate Qt 5'spropagateComposedEvents feature in Qt 4.Stoddart
O
0
                //消息框
                Rectangle {
                    id:msgRectangle
                    width: Math.min(messageText.implicitWidth +14, listView.width -98)
                    height: messageText.implicitHeight + 16
                    color:  send ? "#9dea6a" : "#eeeeee"
                    radius: 3
                    TextEdit {
                        id: messageText
                        text: content
                        wrapMode: TextEdit.Wrap
                        enabled: true
                        readOnly: true
                        selectByKeyboard: true
                        selectByMouse: true
                        selectedTextColor: "white"
                        persistentSelection:true
                        selectionColor: "#3396FF"

                    }
                    MouseArea{
                        id:text_area
                        width: parent.width
                        height: parent.height
                        acceptedButtons: Qt.LeftButton|Qt.RightButton
                        propagateComposedEvents: true
                        onClicked: {
                            if(mouse.button===Qt.LeftButton){
                                mouse.accepted = false;
                            } else {
                                mouse.accepted = true;
                            }

                        }
                        onPressed: {
                            if(mouse.button===Qt.LeftButton){
                                mouse.accepted = false;
                            } else {
                                mouse.accepted = true
                            }
                        }
                        onReleased:{
                            if(mouse.button===Qt.LeftButton){
                                mouse.accepted = false;
                            } else {
                                mouse.accepted = true
                            }
                        }
                        onDoubleClicked:{
                            if(mouse.button===Qt.LeftButton){
                                mouse.accepted = false;
                            } else {
                                mouse.accepted = true
                            }
                        }
                        onPositionChanged:{
                            if(mouse.button===Qt.LeftButton){
                                mouse.accepted = false;
                            } else {
                               mouse.accepted = true
                            }
                        }
                        onPressAndHold:{
                            if(mouse.button===Qt.LeftButton){
                                mouse.accepted = false;
                            } else {
                                mouse.accepted = true
                            }
                        }
                   }
                }
Oxytocic answered 8/9, 2018 at 19:21 Comment(1)
this sames resoved,by BaCaRoZzo and szotsaki Method,thank you very muchPelkey

© 2022 - 2024 — McMap. All rights reserved.