Dragging after long press

I want to drag and drop custom QML buttons after long pressing on them. I have implemented this behavior, however the problem is that after enabling drag

I need to press the button again to start dragging. How do I implement this mechanism if I want to move buttons without releasing after a long press?

Here is my button code ( onReleased

and onLongPressed

are my own signals):

ButtonWidget.SoftButtonUI
{
    id:softButtonDelegate2
    x:500
    y:300
    labelText: "button"
    iconImageSource: path
    isGrayedOut: false

    Drag.active: dragArea2.drag.active
    Drag.hotSpot.x: 10
    Drag.hotSpot.y: 10
    onReleased:
    {
        console.log("onClicked")
    }

    onLongPressed:
    {
        console.log("onLongPressed")
        dragArea2.enabled = true
    }

    MouseArea {
        id: dragArea2
        enabled: false
        anchors.fill: parent
        drag.target: parent
        onReleased: parent.Drag.drop()
        onClicked: {
            console.log("MouseArea onClicked")
        }
        onPressAndHold: {
            console.log("MouseArea  onPressAndHold")
        }
    }
}

      

Any idea?

+3


source to share


1 answer


Generally speaking, you can connect various signals and perform concatenation operations as discussed on this page . You should take a look at it as it is full of pleasant and useful information.

However, when it comes to mouse events, an interesting approach to event concatenation is defined by MouseEvent

acceptation. The documentation says MouseEvent::accepted

:

The setting when true prevents the mouse event from propagating to items below this item. Typically, if an element is acted upon by a mouse event, then it must be received so that the elements are lower in the stacking order also does not respond to the same event.

In this case, we can take the opposite approach without accepting the event. This way, the event pressed

can be used to both activate the drag and to actually execute it. MouseEvent

May then be received (implicitly) in an event release

that fires at the end of the drag.



Here's a simple example following this approach. When the mouse is pressed and hold the button drag.target

and dragging will start, while when the mouse drag.target

is released it will be removed, removing the dragging behavior. To test it, just click and hold the mouse over the rectangle, and when it changes color, just drag it.

import QtQuick 2.4
import QtQuick.Controls 1.3

ApplicationWindow {
    width: 300
    height: 300
    visible: true

    Rectangle {
        id: item
        border.width: 2
        x: 100
        y: 100
        width: 100
        height: 100
        state: "BASE"

        states: [
            State {
            name: "BASE"
            PropertyChanges { target: mouseArea; drag.target: undefined}
            PropertyChanges { target: item; color: "steelblue"}
        },
            State {
            name: "DRAGGABLE"
            PropertyChanges { target: mouseArea; drag.target: item}
            PropertyChanges { target: item; color: "darkblue"}
        }
        ]


        MouseArea {
            id: mouseArea
            anchors.fill: parent
            drag{
                // target:  NOT SET HERE
                minimumX: 0
                minimumY: 0
                maximumX: parent.parent.width - parent.width
                maximumY: parent.parent.height - parent.height
                smoothed: true
            }

            onPressAndHold: {
                item.state = "DRAGGABLE"
                mouse.accepted = false      // mouse event is USED but NOT CONSUMED...
            }

            onReleased: {
                item.state = "BASE"         // mouse event acceptation occurs here!
            }
        }
    }
}

      

This simple approach should work great with your custom signals too.

+1


source







All Articles