0

(QtQuick 2.12 on Windows)

I'm trying to drag something invisible, and take advantage of the keys property in DropArea and the Drag.keys property in the Item I'm dragging. The DropArea generates events if it has an empty keys, but if I put anything into it, it doesn't respond at all, even if the dragged Item has matching keys.

Here's Mybutton.qml:

import QtQuick 2.12

Rectangle {
    height:                 100
    width:                  100
    color:                  "white"
    property var keys:      []

    DropArea {
        anchors.fill:           parent
        keys:                   parent.keys
        onEntered:              console.log("entered", keys)
        onExited:               console.log("exited", keys)
        onDropped:              console.log("dropped", keys)
        }

    MouseArea {
        id:                     mouse
        anchors.fill:           parent
        drag.target:            message
        onPressed: {
            message.x = parent.x + mouse.x
            message.y = parent.y + mouse.y
            message.keys = parent.keys
            message.Drag.active = Qt.binding(
                    function() { return drag.active })
            }
        }
    }

and here's main.qml:

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible:    true
    width:      400
    height:     400
    title:      qsTr("TestDrag")
    color:      "black"

    Item {
        id:                     message
        width:                  1
        height:                 1

        property var keys:      []
        Drag.keys:              keys
        Drag.dragType:          Drag.Automatic
        Drag.onDragStarted:     console.log("started", Drag.keys)
        Drag.onDragFinished:    console.log("finished", dropAction)

        onXChanged:             console.log(x, y)
        }

    MyButton { x: 50;  y: 50;  keys: [ "top", "left" ] }
    MyButton { x: 250; y: 50;  keys: [ "top", "right" ] }
    MyButton { x: 50;  y: 250; keys: [ "bottom", "left" ] }
    MyButton { x: 250; y: 250; keys: [ "bottom", "right" ] }
    }

This puts up four squares, and I should be able to drag any one onto the adjacent ones, but not the opposite corner because it doesn't share any keys. But I can't drag anything onto anything. If I comment out the keys on one of the buttons, then I can obviously drop any of the others onto it, proving that the invisible Item is actually being dragged where I think it is.

The documentation is pretty unclear, so I expect I'm probably doing something wrong. But what?

Or is there a simpler way to do drag and drop, if I don't want to drag an actual visual item? I just want the cursor to change shape based on whether it's over something it can drop on.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Paul DeRocco
  • 403
  • 3
  • 15
  • I'm not sure if "property var keys" would work. Have you tried with a "property alias keys: myDropArea.keys" ? – Massimo Callegari Dec 17 '18 at 16:46
  • Doesn't seem to change anything. – Paul DeRocco Dec 17 '18 at 22:47
  • It seems to work for me when I remove the `Drag.dragType: Drag.Automatic`, Also, little trick: you can change the `Item` to `Rectangle` with `color` to make debugging a bit easier ;-) – Amfasis Dec 18 '18 at 14:32
  • That does appear to be the case. The docs don't say anything about keys only working in Internal mode. In fact, I'd say the drag-and-drop documentation is wretched. – Paul DeRocco Dec 19 '18 at 03:10

2 Answers2

0

With the later interfaces Drag.Automatic and startDrag(), use Drag.mimeData instead of Drag.keys.

If you don't want the drag to actually move anything, you can use these items:

MouseArea{ 
    Drag.mimeData: { 'someKey': '' }   
    onPressed:     { Drag.active = true;   Drag.startDrag(); }
}

DropArea{ keys: ['someKey'] }
really
  • 93
  • 7
  • I know this is old, just leaving an answer for next viewers about something I needed to solve myself. – really Sep 27 '22 at 22:50
0

Was stumped by this as well, and by using really's answer realized that 'someKey' in this scenario is the key used by the DropArea, and additional data can still be added to the drag operation if needed like so:

MouseArea{ 
    Drag.dragType: Drag.Automatic
    Drag.mimeData: { 
        'someKey': '',
        'text/plain': "test_string" 
    }   
    onPressed:     { Drag.active = true;   Drag.startDrag(); }
}

DropArea{ 
    keys: 'someKey'
    onDropped: {
        if (drop.hasText) {
            console.log("Drop Keys: " + drop.keys)
            console.log("Drop Text: " + drop.text)
        }
    }
}

Outputs:

Drop Keys: someKey,text/plain
Drop Text: test_string