[Interest] propagateComposedEvents-like behavior with qt controls 2 components (no C++)

Shawn Rutledge Shawn.Rutledge at qt.io
Mon Sep 25 12:00:16 CEST 2017


> On 25 Sep 2017, at 09:28, Daniel d'Andrada <daniel.dandrada at luxoft.com> wrote:
> 
> Hi All,
> 
> I wanna have the following (A):
> 
> Foo {
>    Button {}
> }
> 
> or (B):
> 
> Item {
>    Button {}
>    Foo {}
> }
> 
> Where "Foo" is an item that is interested only in drag gestures. So when
> one is performed it does its thing. It ignores clicks, letting them go
> to the Button element inside/behind it.

> So A is a QQuickItem::filtersChildMouseEvents way of doing things (like
> Flickable), whereas B is a MouseArea::propagateComposedEvents approach.
> 
> B is not an option as QtQuick.Controls2 are not MouseArea based, so it
> just won't work.

So you just want a draggable Button, right?

If Foo is MouseArea, it must grab the press in order to get updates at all.  If it does not grab, then Button grabs.  It can work if MouseArea is a filtering parent, as documented for MouseArea’s drag.filterChildren property:

import QtQuick 2.0
import QtQuick.Controls 2.2

Item {
    width: 200; height: 200
    MouseArea {
        width: button.width; height: button.height
        drag.target: button
        drag.filterChildren: true
        Button {
            id: button
            text: "Drag me"
            onClicked: console.log("clicked")
        }
    }
}

although ATM I’m seeing a bug that it only works once.  The documented way, having a wrapper item so that you can set drag.target: parent, works better:

import QtQuick 2.0
import QtQuick.Controls 2.2

Item {
    width: 200; height: 200
    Item {
        width: button.width; height: button.height
        MouseArea {
            anchors.fill: parent
            drag.target: parent
            drag.filterChildren: true
            Button {
                id: button
                text: "Drag me"
                onClicked: console.log("clicked")
            }
        }
    }
}

> To implement Foo as in option A I would have to resort to C++. But I
> would like a pure-QML solution for this. Is it possible?

A nicer way: theoretically you ought to be able to do

import QtQuick 2.0
import QtQuick.Controls 2.2
import Qt.labs.handlers 1.0

Item {
    Button {
        DragHandler { }
    }
}

on 5.10 branch; but ATM if you do that, you can drag the button, but you can’t click it.

IMO we need to make that work in 5.10.  But we still have some trouble with grab conflict: the DragHandler gets a passive grab on press, which is fine, and is intended to mean that it will get the updates without preventing the Button from grabbing; but it also accepts the press event, and therefore Button doesn’t see it.  If we make it so that Button does see the press (keep delivering even though the event was already accepted), then Button does an exclusive grab, and then DragHandler doesn’t get the updates when you start dragging.  So I’ve been trying to sell the idea for several months that events need to be delivered to passive grabbers regardless of the exclusive grab.  The patches languish because people aren’t convinced yet that it’s the right approach.

The alternative I can see is for the DragHandler not to accept the event, so that it keeps propagating.

QTBUG-63395 to keep track of that.

I hope we get it fixed soon one way or another.



More information about the Interest mailing list