Results 1 to 11 of 11

Thread: QTreeWidget Drag and Drop

  1. #1

    Default QTreeWidget Drag and Drop

    Hello,

    I have a problem, with drag and drop in a qtreewidget. I try to use drag in drop inside a QTreewidget (qt version 4.3.3). I found this simple tutorial (see "Drop to customized QTreeWidget") on the web:

    http://sector.ynet.sk/qt4-tutorial/dnd.html

    It works, but there is a problem, that was already mentioned (but not answered) in:

    http://www.qtcentre.org/forum/f-newb...drop-5910.html

    For a CopyAction, the dropMimeData function is called, and I can use the QMimeData do get the information I need. For a MoveAction (i.e. if the Shift Key is pressed while dragging&dropping) the dropMimeData function is not called - but anyhow the dragged/dropped items are moved in the QTreeWidget. The behaviour of the dragging and dropping is "nearly" as expected, but I am not able to "react" to MoveActions.

    Is it a bug or a feature that the dropMimeData function is not called for MoveActions? If it is a bug, is it already fixed? If it's a feature - what is the correct way to get in control of "what happens after a MoveAction"?

    Thank you very much in advance!

    Tdent

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTreeWidget Drag and Drop

    Could you prepare a minimal compilable example reproducing the problem? I've used MoveActions with models and they worked just fine - dropMimeData was called.

  3. #3

    Default Re: QTreeWidget Drag and Drop

    Hi,

    sorry it took so long. Here is my (very simple) tree widget


    ----------------------------------------------------------------------------
    Qt Code:
    1. #include "myQTTreeWidget.h"
    2.  
    3. #include <QDragEnterEvent>
    4. #include <QDragMoveEvent>
    5. #include <QList>
    6.  
    7.  
    8. myQTTreeWidget::myQTTreeWidget(QWidget* parent)
    9. : QTreeWidget(parent)
    10. {
    11. setAcceptDrops(true);
    12. setDragEnabled(true);
    13.  
    14. setDragDropMode(QAbstractItemView::DragDrop);
    15. setSelectionMode(QAbstractItemView::ExtendedSelection);
    16. setEditTriggers(QAbstractItemView::SelectedClicked);
    17.  
    18. setHeaderLabel("Name");
    19. setColumnCount(1);
    20.  
    21. QTreeWidgetItem *item1 = new QTreeWidgetItem(this);
    22. QTreeWidgetItem *item2 = new QTreeWidgetItem(this);
    23. QTreeWidgetItem *item3 = new QTreeWidgetItem(this);
    24. QTreeWidgetItem *item4 = new QTreeWidgetItem(this);
    25.  
    26. item1->setText(0,"hello");
    27. item2->setText(0,"world!");
    28. item3->setText(0,"whats");
    29. item4->setText(0,"up?");
    30.  
    31. }
    32.  
    33. myQTTreeWidget::~myQTTreeWidget()
    34. {
    35. }
    36.  
    37. void myQTTreeWidget::dragEnterEvent(QDragEnterEvent *e)
    38. {
    39. e->accept();
    40. }
    41.  
    42. void myQTTreeWidget::dragMoveEvent(QDragMoveEvent *e)
    43. {
    44. e->accept();
    45. }
    46.  
    47. QMimeData *myQTTreeWidget::mimeData(const QList<QTreeWidgetItem *> items) const
    48. {
    49. return new QMimeData;
    50. }
    51.  
    52. bool myQTTreeWidget::dropMimeData ( QTreeWidgetItem * newParentPtr, int index, const QMimeData * data, Qt::DropAction action )
    53. {
    54. return true;
    55. }
    56.  
    57. Qt::DropActions myQTTreeWidget::supportedDropActions () const
    58. {
    59. return Qt::CopyAction|Qt::MoveAction;
    60. }
    To copy to clipboard, switch view to plain text mode 
    -----------------------------------------------------------------------------

    If you want to reproduce the behaviour, you can place a breakpoint into dropMimeData (or some kind of fprintf(...) output ). You will see that this function is called if you try to drag & drop one of the items (without pressing Shift!). But it is not called if you press the Shift key while you're dragging/dropping the item. If you try to drag&drop an item without pressing Shift - nothing happens after dropping the item (that's ok, the drop function is empty). If you drag&drop an item while the Shift key is pressed, then the item is moved after dropping it (wherever this behaviour is implemented).

    Maybe there is something totally wrong with my code. Maybe I made something very stupid? Any suggestion is very welcome.

    Thanks, take care

  4. #4

    Default Re: QTreeWidget Drag and Drop

    I added the following lines:

    Qt Code:
    1. void myQTListView::dropEvent( QDropEvent *e )
    2. {
    3. fprintf(stderr,"dropped\n");
    4. QTreeWidget::dropEvent(e);
    5. }
    To copy to clipboard, switch view to plain text mode 

    The dropEvent is called but it does not reach the dropMimeData funtion. I guess I have to build some qt debug libs...

    But still: Any suggestion is very wellcome.

  5. #5
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: QTreeWidget Drag and Drop

    QAbstractItemModel::dropMimeData() is called by QAbstractItemView::dropEvent() so reimplementing dropEvent() without calling the base class implementation prevents dropMimeData() from being called. Furthermore, reimplementing other drag and drop related event handlers, again, without calling the base class implementation like in the code above, prevents QAbstractItemView DND from functioning properly. Take a look at src/gui/itemviews/qabstractitemview.cpp and see what QAbstractItemView::dragEnterEvent() and QAbstractItemView::dragMoveEvent() do. Writing:
    Qt Code:
    1. void myQTTreeWidget::dragEnterEvent(QDragEnterEvent *e)
    2. {
    3. e->accept();
    4. }
    5.  
    6. void myQTTreeWidget::dragMoveEvent(QDragMoveEvent *e)
    7. {
    8. e->accept();
    9. }
    To copy to clipboard, switch view to plain text mode 
    overrides all that functionality with.. nothing.
    J-P Nurmi

  6. #6
    Join Date
    Aug 2008
    Posts
    12
    Thanks
    1
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: QTreeWidget Drag and Drop

    Greetings ,

    In the two functions below override the original events by accepting the event but what next.

    It will accept the event and no action is performed. ( Try emitting a signal within these functions and perform the required actions accordingly )

    void myQTTreeWidget::dragEnterEvent(QDragEnterEvent *e)
    void myQTTreeWidget::dragMoveEvent(QDragMoveEvent *e)

    Regards
    -Ram

  7. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTreeWidget Drag and Drop

    Is it a continuation of the same problem by a different forum user, a completely separate issue or an answer to the original problem? I got completely lost here...

  8. #8

    Default Re: QTreeWidget Drag and Drop

    Thank you very much for your help.

    Even if it's a very silly question, I have to ask it (sorry 'bout that):

    Whats the "correct" way to implement the dragEnterEvent and dragMoveEvent functions - is this the way?


    Qt Code:
    1. void myQTTreeWidget::dragEnterEvent(QDragEnterEvent *e)
    2. {
    3. // always call base class implementation
    4. QTreeWidget::dragEnterEvent(e);
    5.  
    6. if ( isDragEnterPossible(e) )
    7. {
    8. e->accept();
    9. }
    10. else
    11. {
    12. e->ignore();
    13. }
    14. }
    15.  
    16. void myQTTreeWidget::dragMoveEvent(QDragMoveEvent *e)
    17. {
    18. // always call base class implementation
    19. QTreeWidget::dragMoveEvent(e);
    20.  
    21. if ( isDragMovePossible(e) )
    22. {
    23. e->accept();
    24. }
    25. else
    26. {
    27. e->ignore();
    28. }
    29. }
    To copy to clipboard, switch view to plain text mode 

    isDragMovePossible and isDragEnterPossible are member functions, returning a bool value and telling us if dropping is possible.

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTreeWidget Drag and Drop

    The question is why would you want to reimplement them? What's wrong with the default implementation?

  10. #10

    Default Re: QTreeWidget Drag and Drop

    Thank you for your answer.

    So "what is this all about":

    I have an application with lots of different widgets (treeviews, listviews, iconviews .... ). All widgest support dnd (all of them are still old qt3 style, but will/should () be "converted" soon). In my (derived) QTreeView I want do accept the drags from some of the other widgets, but not from all of the other widget. I thought the dragEnterEvent can (has to) be used for defining which events are accepted and which are not:

    Qt Code:
    1. void myQTListView::dragEnterEvent(QDragEnterEvent *e)
    2. {
    3. if ( e )
    4. {
    5. if ( e->provides("mystuff/mything") )
    6. {
    7. e->accept();
    8. }
    9. else
    10. {
    11. e->ignore();
    12. }
    13. }
    14. }
    To copy to clipboard, switch view to plain text mode 



    I also have different items (all derived from QTreeWidgetItem of course) in my treeview. Some of them accept drops and some of them don't. So I use the dragMoveEvent to get the "current dropping target" by calling

    Qt Code:
    1. void myQTListView::dragMoveEvent(QDragMoveEvent *e)
    2. {
    3. QTreeWidgetItem *item = itemAt(e->pos());
    4.  
    5. bool accept = false;
    6.  
    7. if ( item )
    8. {
    9. if ( dynamic_cast<MySpecialListViewItem*>(item) )
    10. {
    11. accept = true;
    12. }
    13. }
    14.  
    15. if ( accept )
    16. {
    17. e->accept();
    18. }
    19. else
    20. {
    21. e->ignore();
    22. }
    23. }
    To copy to clipboard, switch view to plain text mode 

    and check (by dynamic cast) if this (derived) QTreeWidgetItem is one of the items that accept drops.

    I use the event->accept() or event->ignore() function to indicate if dropping is possible or not.

    ps. Sorry that this has become a beginner tutorial on using drag and drop with QTreeViews, maybe I was running completely in the wrong direction?

  11. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTreeWidget Drag and Drop

    But most of what you want is already implemented by default handlers, there is no need to reinvent the wheel. You can tell the widget which types of data it should accept. Take a look at mimeTypes(), mimeData() and dropMimeData().

Similar Threads

  1. QTreeWidget Drag and drop
    By zell99 in forum Newbie
    Replies: 15
    Last Post: 7th August 2010, 13:28
  2. Drag and Drop item inside QTreeWidget
    By nina1983 in forum Qt Programming
    Replies: 4
    Last Post: 6th July 2008, 11:43
  3. Drag and Drop in a QTreeWidget subclass
    By kishore in forum Qt Programming
    Replies: 2
    Last Post: 14th May 2008, 07:12
  4. Drag an item from QTreeWidget and drop in TableView
    By steg90 in forum Qt Programming
    Replies: 8
    Last Post: 18th May 2007, 11:42
  5. Drag and drop revisited
    By Big Duck in forum Newbie
    Replies: 2
    Last Post: 30th June 2006, 16:41

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.