Search code examples
drag-and-dropqmldrag

Can QML drag-and-drop mechanic work without drag item moving?


I have a listview and a rectangle on top of it. The ListView's delegates have DropAreas in them and the rectangle has drag enabled on Y axis with its relevant properties (hotspot, target).

When I move the rectangle up and down on the ListView, the DropAreas of the delegates are registering onEntered signals. Working as intended.

However, I am using SmoothedAnimation to scroll the list up and down when the rectangle is at the most top and bottom coordinates (list.y = 0 and list.height). So the rectangle is not moving, and the DropAreas of the list's delegates are moving under it. In that case, the onEntered is not registered because there is no dragging, the rectangle is completely still and although its hotspot is entering and leaving the DropAreas, there is no interaction.

This is because dragging mechanic is sending events all the time when moving and any DropAreas it comes inside can register the event. In my case there is no dragging and therefore no events.

Question: Can drag events be manually activated? Can I somehow simulate drag?


Solution

  • I have managed to induce drag events by manually changing the hotSpot property of the rectangle above the list. QML Drag documentation says:

    Changes to hotSpot trigger a new drag move with the updated position.

    So I have done this every time Listview contentY changes (vertical scrolling happens)

        onContentYChanged:
        {
            rectangle.Drag.hotSpot.x += 0.0001
            rectangle.Drag.hotSpot.x -= 0.0001
        }
    

    In hindsight, however, this is a 'hacky' solution. hotSpot property is a QPointF class property (link). This means it can be set using various methods (setX, setY, rx, ry..). For example, this:

    rectangle.hotSpot += Qt.point(0,0)
    

    or

    rectangle.hotSpot = Qt.point(rectangle.hotSpot.x,rectangle.hotSpot.y)
    

    should work in theory by resetting the hotSpot point when contentY changes, but testing revealed it unfortunately does not trigger a new drag move. (bug or intended, I don't know)

    Now some of you that are more into Qt and QML might know more about this and how to properly adress the issue, but the above solution works for me and after testing everything I could imagine to get a cleaner solution, I settled on it.