Drag and Drop catches mouse



  • Hello everyone,

    I noticed a strange behavior while implementing a listview with draggable elements. My application consists in a QMainWindow with two docks each containing a QQuickWidget with a ListView, I want to be able to do drag and drop between those ListViews

    The drag and drop works, however, once the drag is completed the source item's MouseArea will catch the next mouse click in the qquickwidget.
    I modified an example to illustrate my issue. Take the "Qt Quick Widgets Example" and replace the content of rotatingsquare.qml with the following code.

    import QtQuick 2.2
    import QtQuick.Layouts 1.0
    
    ListView {
        id: root
        width: 320
        height: 480
    
        highlight: Rectangle {
            color: "lightsteelblue"
            radius: 5
        }
    
        model: ["Lorem ipsum dolor sit amet",
          "consectetur adipiscing elit",
          "sed do eiusmod tempor incididunt ut labore",
          "et dolore magna aliqua."
        ]
    
        delegate: Item {
            id: item
            property string display : modelData
    
            height: 50
            width:root.width
    
            Text {
                id: text
                anchors.fill: parent
                text: item.display + " " + model.index + " " + (mouseArea.drag.active ? "drag active" : "")
                wrapMode: Text.WordWrap
            }
    
            DropArea {
                property int index: model.index
    
                anchors.fill: parent
                keys: ["text/plain"]
                onEntered: {
                    text.color = "red"
                }
                onExited: {
                    text.color = "black"
                }
                onDropped: {
                    text.color = "black"
                    if (drop.hasText) {
                        item.display = drop.text
                        drop.acceptProposedAction()
                    }
                }
            }
            MouseArea {
                id: mouseArea
                anchors.fill: parent
                drag.target: draggable
    
                onClicked: root.currentIndex = model.index
            }
            Item {
                id: draggable
                anchors.fill: parent
                Drag.active: mouseArea.drag.active
                Drag.hotSpot.x: 0
                Drag.hotSpot.y: 0
                Drag.mimeData: { "text/plain": item.display }
                Drag.dragType: Drag.Automatic
                Drag.onDragStarted: {
                  print("Drag started " + model.index)
                }
            } // Item
        }
    }
    
    
    

    This code is inspired by "Qt Quick Examples - externaldraganddrop".
    The Qml scene consists in a ListView with draggable text items. You can also click on an item to select it.
    Once a an item is dragged (it doesn't even have to be dropped on an other item) it will catch the next click on the Qml scene.
    You can check this by dragging an other item (the drag will originate from the wrong item) or attempting to select an other item.

    This behavior does not reproduce in a pure Qml application, nor does it reproduce if the items aren't part of a ListView (the original externaldraganddrop works juste fine inside a QQuickWidget).

    Does anyone know how to fix this behavior ?

    Thank you


  • Moderators

    @Smatcher It could be because drag.target in MouseArea is set to Item draggable. It should point to delegate item i.e Item with id item itself. Meaning don't create another item (i.e the one where you have set Drag.* properties) instead set those properties for root item (i.e Item with id item) itself.



  • @p3c0 This isn't what i'm trying to do. Setting the whole item as the drag.target would make the item follow the cursor and since the item can't be drawn outside of the Qml scene it would clip as soon as the pointer leaves the dock. I use a non visual "draggable" Item to be the drag.target like in the externaldraganddrop example.

    I tried what you suggested and noticed something strange however.

    • Inside a QQuickWidget : the item will not follow the cursor during the drag and drop but follow it after the user releases the mouse button ("locking" the mouse in the process). MouseArea.onReleased is not called after the drag and drop.

    • Inside a full Qml application : the item will not follow the cursor during the drag and drop but move to the cursor when the user releases the mouse button. MouseArea.onReleased is called after the drag and drop.

    Edit : I just found a bug report for the same behavior (https://bugreports.qt.io/browse/QTBUG-40773).



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.