Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Drag and Drop catches mouse
Forum Updated to NodeBB v4.3 + New Features

Drag and Drop catches mouse

Scheduled Pinned Locked Moved QML and Qt Quick
qquickwidgetqmllistviewdrag and drop
3 Posts 2 Posters 3.0k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Smatcher
    wrote on last edited by
    #1

    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

    p3c0P 1 Reply Last reply
    0
    • S Smatcher

      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

      p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by
      #2

      @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.

      157

      S 1 Reply Last reply
      0
      • p3c0P p3c0

        @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.

        S Offline
        S Offline
        Smatcher
        wrote on last edited by Smatcher
        #3

        @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).

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved