Results 1 to 2 of 2

Thread: When should QTreeWidget::dropMimeData be called?

  1. #1
    Join Date
    Mar 2014
    Posts
    7
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default When should QTreeWidget::dropMimeData be called?

    I'm trying to create a dialog with a (derived) QListWidget on the left and a (derived) QTreeWidget on the right. Users should be able to drag items from the list widget and drop them into the tree widget. Child items in the tree widget can also be moved to a different parent (top level item).

    I initially reimplemented startDrag() in the list widget, and dragEnterEvent(), dragMoveEvent(), and dropEvent() in the tree widget. I encoded some mime data in startDrag(), and decoded it in dropEvent(), and removed the dragged-and-dropped items from the list widget if all went well. This all worked more or less, but I couldn't figure out how to make the "drop indicator" appear in the tree widget when I was dragging an item in. While searching for a solution, I discovered I was doing things all wrong, and tried a different approach.

    I've reimplemented mimeData() in the list widget, and reimplemented dropMimeData() in the tree widget. This doesn't work: dropMimeData() is never called. I've got the following options set up on the tree widget:

    Qt Code:
    1. theTreeWidget->setDragEnabled(true);
    2. theTreeWidget->setAcceptDrops(true);
    3. theTreeWidget->setDragDropMode(QAbstractItemView::InternalMove);
    To copy to clipboard, switch view to plain text mode 

    So first question: Why isn't dropMimeData() called? I tried changing the drag drop mode to DragDrop, because I though this might help. When I do, dropMimeData() is called, but ONLY when I drag and drop items from within the tree, not from the list widget. Also, tree widget items are copied, rather than moved (I guess this is expected behaviour). So I tried to reimplement the supportedDropActions() function so that only MoveAction is returned. Now dropMimeData is no longer called, and I get weird behaviour:

    1. When I have two top-level items, and one child item under the first, I try to move the child to the other top-level item. The child becomes a top-level item and its parent is deleted. Some screen shots, before: before.png and after: after.png

    2. When I have two top-level items, and two children under the first, I try to move the second child to the other top-level item. The child moves appropriately, but its "sibling" is deleted. Before: before2.png, and after:after2.png

    Second question: Is this normal behaviour? I've looked through my code, and there's only one function where I delete or take items from the tree widget, and it isn't called during dragging and dropping (I added a qDebug() call to make sure).

  2. #2
    Join Date
    Mar 2014
    Posts
    7
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Lightbulb Re: When should QTreeWidget::dropMimeData be called?

    I've figured out most of my problem. I'm still not sure about the weirdness when QTreeWidget::supportedDropActions() is reimplemented, but I've got the rest of it. I'm posting my solution because I've seen other related questions and I think that my solution might lead to an answer for a few people.

    1. In addition to reimplementing QListWidget::mimeData() and QTreeWidget::dropMimeData(), I needed to reimplement mimeTypes() in both classes. This was well-documented in the http://doc.qt.io/qt-4.8/model-view-programming documentation, but apparently I can't read.
    2. Using QTreeWidget::setDragDropMode() to set the drag/drop mode to QAbstractItemView::DragDrop is important for receiving drag/drop events from the list widget as well as allowing internal drag and drop (within the tree widget).
    3. I also had to reimplement QTreeWidget::mimeData() so that internal drag and drop events in the tree widget would be handled properly. This probably wasn't entirely necessary, but I think it simplified forcing internal drag and drop events to be move actions later.
    4. At this stage, drag and drop worked, but only to copy items. Reimplementing QTreeWidget::supportedDropActions() to allow only Qt::MoveAction did NOT work. As stated above, it just resulted in items being deleted that shouldn't have been... I'm pretty sure this is a Qt bug (I'm using Qt 4.8).
    5. Getting my whole setup to move things (as opposed to copying) required reimplementing QListWidget::startDrag() QTreeWidget::startDrag() in order to create QDrag instances that executed MoveActions.


    Without further ado, here's a working example!

    MyDialog.cpp
    MyDialog.h
    main.cpp
    dropMimeData.pro

Similar Threads

  1. Replies: 0
    Last Post: 21st October 2013, 10:16
  2. Derived dropMimeData never called
    By davsa in forum Qt Programming
    Replies: 1
    Last Post: 18th August 2012, 04:49
  3. Replies: 2
    Last Post: 21st March 2011, 23:00
  4. Replies: 2
    Last Post: 17th March 2008, 13:53
  5. Replies: 8
    Last Post: 1st May 2007, 23:35

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.