Hi.

In the following example (#1), I want both the MouseArea to be clickable and 
the scroll bars to be draggable:

    import QtQuick 2.7
    import QtQuick.Window 2.2
    import QtQuick.Controls 2.0
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
        id: root
    
        Flickable {
            anchors.fill: parent
            contentWidth: rect.width
            contentHeight: rect.height
            boundsBehavior: Flickable.StopAtBounds
    
            ScrollBar.vertical: ScrollBar {
                id: verticalScrollBar
                Binding {
                    target: verticalScrollBar
                    property: "active"
                    value: verticalScrollBar.hovered
                }
            }
    
            Rectangle {
                id: rect
                width: 640
                height: 1000
                gradient: Gradient {
                    GradientStop {
                        position: 0
                        color: "#e03389"
                    }
                    GradientStop {
                        position: 1
                        color: "#20ae24"
                    }
                }
            }
        }
    
        MouseArea {
            id: mouseArea
            anchors.fill: parent
        }
    
        Rectangle {
            id: mouseAreaRect
            anchors.fill: parent
            color: "transparent"
            border.color: mouseArea.pressed ? "red" : "darkorange"
        }
    }

The mouse area can be clicked, but the scroll bars can't be dragged.

If I move the mouse area below the flickable, the opposite problem occurs: the 
scroll bars can be dragged, but the mouse area can't be clicked. Example #2:

    import QtQuick 2.7
    import QtQuick.Window 2.2
    import QtQuick.Controls 2.0
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
        id: root
        
        MouseArea {
            id: mouseArea
            anchors.fill: parent
        }
        
        Flickable {
            anchors.fill: parent
            contentWidth: rect.width
            contentHeight: rect.height
            boundsBehavior: Flickable.StopAtBounds
    
            ScrollBar.vertical: ScrollBar {
                id: verticalScrollBar
                Binding {
                    target: verticalScrollBar
                    property: "active"
                    value: verticalScrollBar.hovered
                }
            }
    
            Rectangle {
                id: rect
                width: 640
                height: 1000
                gradient: Gradient {
                    GradientStop {
                        position: 0
                        color: "#e03389"
                    }
                    GradientStop {
                        position: 1
                        color: "#20ae24"
                    }
                }
            }
        }
   
        Rectangle {
            id: mouseAreaRect
            anchors.fill: parent
            color: "transparent"
            border.color: mouseArea.pressed ? "red" : "darkorange"
        }
    }

I remembered that MouseArea has a preventStealing property. Its documentation 
says:

    This property holds whether the mouse events may be stolen from this 
MouseArea.

    If a MouseArea is placed within an item that filters child mouse events, 
such as Flickable, the mouse events may be stolen from the MouseArea if a 
gesture is recognized by the parent item, e.g. a flick gesture. If 
preventStealing is set to true, no item will steal the mouse events.

I only want the gradient rectangle to be the child of the flickable, but I was 
curious if it would work, so I moved the mouse area in there anyway. Example #3:

    import QtQuick 2.7
    import QtQuick.Window 2.2
    import QtQuick.Controls 2.0
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
        id: root
    
        Flickable {
            anchors.fill: parent
            contentWidth: rect.width
            contentHeight: rect.height
            boundsBehavior: Flickable.StopAtBounds
    
            ScrollBar.vertical: ScrollBar {
                id: verticalScrollBar
                Binding {
                    target: verticalScrollBar
                    property: "active"
                    value: verticalScrollBar.hovered
                }
            }
    
            Rectangle {
                id: rect
                width: 640
                height: 1000
                gradient: Gradient {
                    GradientStop {
                        position: 0
                        color: "#e03389"
                    }
                    GradientStop {
                        position: 1
                        color: "#20ae24"
                    }
                }
            }
    
            MouseArea {
                id: mouseArea
                anchors.fill: parent
                preventStealing: true
            }
        }
    
        Rectangle {
            id: mouseAreaRect
            anchors.fill: parent
            color: "transparent"
            border.color: mouseArea.pressed ? "red" : "darkorange"
        }
    }

To my surprise, it worked. I thought that the MouseArea would block the scroll 
bars. From some debugging, I can see that the scroll bar is constructed before 
the mouse area, so I would have thought that it would be below it in terms of 
stacking order.

I then wondered if I could get away with not even setting preventStealing to 
true, and it turns out I could.

I have some questions about all of this:

- In example #2, why is Flickable happy to steal events that it doesn't do 
anything with? Shouldn't it see that it wasn't a "flick" and ignore the event, 
so that it goes to the next highest item in the stacking order (the mouse area)?

For instance, in the following example, there are two sibling mouse areas. The 
lower mouse area gets the press event, because the one above it wasn't 
interested in it:

    import QtQuick 2.7
    import QtQuick.Window 2.2
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
        id: root
    
        MouseArea {
            anchors.fill: parent
    
            Rectangle {
                anchors.fill: parent
                color: "transparent"
                border.color: parent.pressed ? "black" : "green"
                border.width: 5
            }
        }
    
        MouseArea {
            anchors.fill: parent
            onPressed: mouse.accepted = false
    
            Rectangle {
                anchors.fill: parent
                anchors.margins: 10
                color: "transparent"
                border.color: parent.pressed ? "red" : "darkorange"
                border.width: 5
            }
        }
    }
    
This is the behaviour I'd expect.

- Why aren't the scroll bars blocked by the mouse area in example #3?

- Why does example #3 work if I remove "preventStealing: true"?

Cheers.
_______________________________________________
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest

Reply via email to