Results 1 to 16 of 16

Thread: QTreeWidget Drag and drop

  1. #1
    Join Date
    Mar 2007
    Posts
    6
    Qt products
    Qt4
    Platforms
    Windows

    Question QTreeWidget Drag and drop

    Hi, this is my first post here. I'm new to QT and I have to do special things with my QTreeWidget reguarding Drag and drop.

    When I drop an item, I need to make a verification before it is "finalized". I need to know exactly which functions need to be reimplemented? I couldn't find good examples for this.

    Do I need to play with Events? (mouseMoveEvent, mousePressEvent, dragMoveEvent?)
    QDrag and QMimeData? (dropMimeData() ?)

    I made a new class MyTreeWidget() : public QTreeWidget() so I can reimplement some of these functions, but I'm not sure which ones I should use. I need to have access to the QTreeWidgetItem that is being dragged and the one on which it is dropped (so the validation will be done when it's dropped).

    Any help would be greatly appreciated. Thank you!

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

    Default Re: QTreeWidget Drag and drop

    You need to reimplement dropMimeData and possibly dragEnterEvent and dragMoveEvent (but it depends when you want to do the check).

  3. #3
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTreeWidget Drag and drop

    Quote Originally Posted by zell99 View Post
    I made a new class MyTreeWidget() : public QTreeWidget() so I can reimplement some of these functions, but I'm not sure which ones I should use. I need to have access to the QTreeWidgetItem that is being dragged and the one on which it is dropped (so the validation will be done when it's dropped).!
    The function you have to reimplement is obviously dropMimeData(). It gives you an access to the target item but not directly to the dragged one(s). There are two ways to workaround this :
    • Reimplementing mimeData(QList<QTreeWidgetItem*>) so that proper (custom) QMimeData object is created when dragging and retrieving and item list from it
    • using the list of selectedItems()
    Hope this helps.
    Current Qt projects : QCodeEdit, RotiDeCode

  4. #4
    Join Date
    Mar 2007
    Posts
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTreeWidget Drag and drop

    Thanks for your answers this far.

    I have another question. I want the default action, when drag-and-dropping on my QTreeWidget, to be a "move" action instead of a "copy". I know if I hold shift while dragging, it will do a "move" action but I can't find where this decision is made.

    Can anyone direct me to the function(s) that I need to work with here?

    Thank you very much.

    PS: I am using Qt 4.2.2

  5. #5
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTreeWidget Drag and drop

    Quote Originally Posted by zell99 View Post
    Thanks for your answers this far.

    I have another question. I want the default action, when drag-and-dropping on my QTreeWidget, to be a "move" action instead of a "copy". I know if I hold shift while dragging, it will do a "move" action but I can't find where this decision is made.

    Can anyone direct me to the function(s) that I need to work with here?
    You can basically restrain the type of actions to be allowed through the supportedDropActions() virtual method. Then the most important step is what you actually do in the dropMimeData() method. Indeed you can choos to always move items or always copy them, regardless to the action parameter or you can decide to stick to that parameter and allo both actions...
    Current Qt projects : QCodeEdit, RotiDeCode

  6. #6
    Join Date
    Mar 2007
    Posts
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTreeWidget Drag and drop

    The thing is that in a QTreeWidget the default drag and drop action is Copy, to make a Move action you have to hold SHIFT. I was wondering if I could change it so I don't have to hold shift in order to make a Move action. I restricted actions to MoveAction using the "supportedActions()" function and "setSupportedActions()". Now, it works if I shift-drag but if I just drag normally it doesn't work (since it's trying to make a Copy action which is not supported)

    I have another newbie question. I have a class (MyMainWindow) which reimplements QMainWindow and in that class, I created the MyTreeWidget class (which inherits QTreeWidget). I understand that in MyTreeWidget I can use the "parentWidget()" function which returns a QWidget pointer on my parent (MyMainWindow), but how can I have access to the private variables I have in MyMainWindow, since the pointer is of QWidget type?

    Thanks.

  7. #7
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTreeWidget Drag and drop

    Quote Originally Posted by zell99 View Post
    The thing is that in a QTreeWidget the default drag and drop action is Copy, to make a Move action you have to hold SHIFT. I was wondering if I could change it so I don't have to hold shift in order to make a Move action. I restricted actions to MoveAction using the "supportedActions()" function and "setSupportedActions()". Now, it works if I shift-drag but if I just drag normally it doesn't work (since it's trying to make a Copy action which is not supported)
    You can always reimplement QWidget::mousePressEvent(QMouseEvent*) and create your own QDrag object specifying the drag type (move or copy) by hand.

    Quote Originally Posted by zell99 View Post
    I have another newbie question. I have a class (MyMainWindow) which reimplements QMainWindow and in that class, I created the MyTreeWidget class (which inherits QTreeWidget). I understand that in MyTreeWidget I can use the "parentWidget()" function which returns a QWidget pointer on my parent (MyMainWindow), but how can I have access to the private variables I have in MyMainWindow, since the pointer is of QWidget type?
    You shouldn't ask two very different questions in the same thread (and especially you shouldn't ask this one at all :P ). All you have to do is to use
    Qt Code:
    1. qobject_cast<MyMainWindow*>(parentWidget())
    To copy to clipboard, switch view to plain text mode 
    to get a pointer of the type you're interested in. Then you shall use friendship to let your tree widget access private members of your main window.
    Current Qt projects : QCodeEdit, RotiDeCode

  8. #8
    Join Date
    Mar 2007
    Posts
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTreeWidget Drag and drop

    Quote Originally Posted by fullmetalcoder View Post
    You shouldn't ask two very different questions in the same thread (and especially you shouldn't ask this one at all :P ). All you have to do is to use
    Qt Code:
    1. qobject_cast<MyMainWindow*>(parentWidget())
    To copy to clipboard, switch view to plain text mode 
    to get a pointer of the type you're interested in. Then you shall use friendship to let your tree widget access private members of your main window.
    I tried to cast it before but it didn't work. I was using static_cast though, that might be the reason why. Thanks for your help!

    I noticed something odd now though. When I am doing a MoveAction on MyTreeWidget, the MyTreeWidget::dropMimeData() function doesn't get called. It gets called from a CopyAction though. How do I make it so that it gets called from a MoveAction too? (My drop acceptation is in dropMimeData())

    Thanks and sorry for all the newbish questions
    Last edited by zell99; 7th March 2007 at 16:33.

  9. #9
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTreeWidget Drag and drop

    [quote=zell99;30976]
    I noticed something odd now though. When I am doing a MoveAction on MyTreeWidget, the MyTreeWidget::dropMimeData() function doesn't get called. It gets called from a CopyAction though. How do I make it so that it gets called from a MoveAction too? (My drop acceptation is in dropMimeData())/quote]
    A piece of code would be of a great help here (including supportedDropActions() and dropMimeData() and anything else you think may be relevant)...
    Current Qt projects : QCodeEdit, RotiDeCode

  10. #10
    Join Date
    Mar 2007
    Posts
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTreeWidget Drag and drop

    Quote Originally Posted by fullmetalcoder View Post
    A piece of code would be of a great help here (including supportedDropActions() and dropMimeData() and anything else you think may be relevant)...
    Sure, here is the constructor:

    Qt Code:
    1. GgdTreeWidget::GgdTreeWidget(QWidget * parent) : QTreeWidget(parent)
    2. {
    3. // Only the Move action is possible
    4. //model()->QAbstractItemModel::setSupportedDragActions(Qt::MoveAction);
    5. }
    To copy to clipboard, switch view to plain text mode 

    The "setSupportedDragActions" is in commentary so I could test a CopyAction. Here is the dropMimeData() function.

    Qt Code:
    1. bool GgdTreeWidget::dropMimeData(QTreeWidgetItem *parent, int index,
    2. const QMimeData *data, Qt::DropAction action)
    3. {
    4. // PROBLEM: FUNCTION IS NOT CALLED FROM A MOVE ACTION !
    5.  
    6. // The destination item is *parent
    7.  
    8. // The item that is being dragged is in selectedItems()
    9. QList<QTreeWidgetItem *> selectList;
    10. QTreeWidgetItem * myDraggedItem;
    11. selectList = this->selectedItems();
    12. myDraggedItem = selectList.at(0);
    13.  
    14. ////////// TEST
    15. GgdMainWindow * myMainWindow = qobject_cast<GgdMainWindow*>(parentWidget());
    16. myMainWindow->setTitleText("dragged=" + myDraggedItem->text(0));
    17. //////////
    18.  
    19. if (parent) idx = indexFromItem(parent);
    20. bool isAccepted = model()->QAbstractItemModel::dropMimeData(data, action , index, 0, idx);
    21. return isAccepted;
    22. }
    To copy to clipboard, switch view to plain text mode 

    Here is the supportedActions()

    Qt Code:
    1. Qt::DropActions GgdTreeWidget::supportedDropActions() const
    2. {
    3. // Only the Move action is possible
    4. return Qt::MoveAction;
    5. }
    To copy to clipboard, switch view to plain text mode 

    If I add "| Qt::CopyAction" and do a normal drag and drop (copy) the dropMimeData function gets called (I tested by placing a Breakpoint in it). If I hold shift and do a move action, it never steps into the dropMimeData function.

    Is that the code you needed?


    Here is the part where I create the TreeWidget from my MainWindow:

    Qt Code:
    1. void GgdMainWindow::createTreeWidget()
    2. {
    3. // Creates and sets dimensions for the Tree Widget
    4. mTree = new GgdTreeWidget(this);
    5. mTree->setGeometry(QRect(10, 10, 171, 411));
    6. mTree->headerItem()->setText(0, QApplication::translate("GgdMainWindow", "Elements", 0, QApplication::UnicodeUTF8));
    7.  
    8. // Sets drag and drop
    9. mTree->setColumnCount(1);
    10. mTree->setSelectionMode(QAbstractItemView::SingleSelection);
    11. mTree->setDragEnabled(true);
    12. mTree->setAcceptDrops(true);
    13. mTree->setDropIndicatorShown(true);
    14. mTree->show();
    15. }
    To copy to clipboard, switch view to plain text mode 

  11. #11
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTreeWidget Drag and drop

    Quote Originally Posted by zell99 View Post
    The "setSupportedDragActions" is in commentary so I could test a CopyAction.
    I've never heard about such a function... What Qt version are you using???

    Quote Originally Posted by zell99 View Post
    Qt Code:
    1. Qt::DropActions GgdTreeWidget::supportedDropActions() const
    2. {
    3. // Only the Move action is possible
    4. return Qt::MoveAction;
    5. }
    To copy to clipboard, switch view to plain text mode 
    If I add "| Qt::CopyAction" and do a normal drag and drop (copy) the dropMimeData function gets called (I tested by placing a Breakpoint in it). If I hold shift and do a move action, it never steps into the dropMimeData function.
    Sounds puzzling... Actually I never faced any trouble when implementing D'nD in tree models. That may come from the fact that I use models of my own and force a move action in dropMimeData() but I can confirm (just tested) that dropMimeData() (of the custom model in my case) gets called when holding shift key down while dragging... Maybe you could send me the full source so that I can do in-depth testing...
    Current Qt projects : QCodeEdit, RotiDeCode

  12. #12
    Join Date
    Mar 2007
    Posts
    6
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTreeWidget Drag and drop

    I'm using 4.2.2. I can send you the source code at the email registered on your account, is that ok?

  13. #13
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTreeWidget Drag and drop

    Quote Originally Posted by zell99 View Post
    I'm using 4.2.2. I can send you the source code at the email registered on your account, is that ok?
    Yep. I'll check it ASAP.
    Current Qt projects : QCodeEdit, RotiDeCode

  14. #14
    Join Date
    Aug 2009
    Posts
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTreeWidget Drag and drop

    Hello, I was wondering if this issue was ever resolved? I'm having the exact same problem with QTableWidget's, the dropMimeData() never gets called.

  15. #15
    Join Date
    Jul 2010
    Posts
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTreeWidget Drag and drop

    Is there a final code out there? I want to inverse the shift-function by move and copy too

  16. #16
    Join Date
    Mar 2009
    Posts
    4
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QTreeWidget Drag and drop

    For QTreeWidget derived class dropMimeData() gets called only when there is a "data drop", so to say. For move operations, it does not get called. It gets called when you try to copy the data. For Move or Internal move operations QTreeWidget::dropEvent() gets called.

    Gopalakrishna Palem
    Creator of CFugue Runtime for Programming Music in C++

Similar Threads

  1. Drag and Drop
    By allensr in forum Qt Programming
    Replies: 1
    Last Post: 11th December 2006, 21:50
  2. Replies: 7
    Last Post: 8th September 2006, 17:19
  3. Drag and drop outside the application
    By jpn in forum Newbie
    Replies: 7
    Last Post: 27th August 2006, 16:37
  4. Drag and drop revisited
    By Big Duck in forum Newbie
    Replies: 2
    Last Post: 30th June 2006, 17:41
  5. Drag 'n Drop problem
    By kiker99 in forum Qt Programming
    Replies: 4
    Last Post: 16th January 2006, 17:35

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.