Page 1 of 2 12 LastLast
Results 1 to 20 of 21

Thread: Drag and drop between model views

  1. #1
    Join Date
    Jun 2006
    Location
    San Jose, CA
    Posts
    53
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Drag and drop between model views

    Hi all,

    I have two table model views. When I drag an item to the other view how can I tell the source view that the drop has been accepted? The idea is to grey out the item which was copied to the other view.

    Any hints?
    Thanks a lot.

  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: Drag and drop between model views

    Return true from QAbstractItemModel::dropMimeData(). Unfortunately you can't access that information from within the source. But if you force a MoveAction, the item will get deleted by the source view. If you want a different behaviour, subclass the view and reimplement startDrag().
    Last edited by wysota; 19th July 2006 at 12:45.

  3. #3
    Join Date
    Jun 2006
    Location
    San Jose, CA
    Posts
    53
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Drag and drop between model views

    As you said the only one who knows that mimedata was sucessfully droped is QAbstractItemModel::dropMimeData() so, I implemented a signal in the target model and a slot in the source model to inform the source that data has been transfered. Is that a resonable way to do that?

    Thanks.

  4. #4
    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: Drag and drop between model views

    Quote Originally Posted by larry104
    Is that a resonable way to do that?
    Not really, but if it works then why not...

  5. #5
    Join Date
    Jun 2006
    Location
    San Jose, CA
    Posts
    53
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Drag and drop between model views

    If you say
    Not really, but if it works then why not...
    how should I do it? I tried the subclassing approach but non of the these

    Qt Code:
    1. void dragEnterEvent(QDragEnterEvent *event);
    2. void dragLeaveEvent(QDragLeaveEvent *event);
    3. void startDrag(Qt::DropActions supportedActions);
    4. void dragMoveEvent(QDragMoveEvent *event);
    5. void dropEvent(QDropEvent *event);
    To copy to clipboard, switch view to plain text mode 

    tell me that the target has really accepted the drop. Do I miss something?
    Thanks.

  6. #6
    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: Drag and drop between model views

    QDrag::start() tells you that and it is called from QAbstractItemView::startDrag(), that's why I said you could reimplement it.

  7. #7
    Join Date
    Jun 2006
    Location
    San Jose, CA
    Posts
    53
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Drag and drop between model views

    I see your point but, still if the user drops the data other than the target model view I wouln't know that. Subclassing startDrag would just allow me to act on the actual move out of my source view - right? There is no real feedback mechanism between source and target.

  8. #8
    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: Drag and drop between model views

    Quote Originally Posted by larry104
    I see your point but, still if the user drops the data other than the target model view I wouln't know that. Subclassing startDrag would just allow me to act on the actual move out of my source view - right? There is no real feedback mechanism between source and target.
    startDrag will notify you in the source view (by the return value from startDrag()). From then you have direct access to the source model (you can connect them through signal and slot then, emiting the signal from the view in this situation is better than from the model), I thought that was what you wanted -- to change the source model after the drop.

  9. #9
    Join Date
    Jun 2006
    Location
    San Jose, CA
    Posts
    53
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Drag and drop between model views

    So, I subclassed startDrag and indeed QDrag::start() tells me that something was moved/copied but as I thought it will tell me when I droped into the target as well as any other application e.g firefox. So, I don't see a difference that the data has been accepted by the target.

  10. #10
    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: Drag and drop between model views

    I have to admit I didn't understand your post

    QDrag::start returns an information if the drag was accepted and with which action. If it was dropped on an invalid target, it will return IgnoreAction, if it was dropped on a valid target but the drop was rejected, it will return IgnoreAction. If it was dropped on a valid target and the target did something with the data (no matter if the target is in the same application as the source or if it's a completely different program), it will return an action telling you what should you do with the data -- copy, move, link or ignore it. If you drop on Firefox and firefox accepts the drop, you'll receive CopyAction. So you'll always know what you should do with the item.

    Does that solve your problem? If you have doubts, please look at the puzzle example bundled with Qt and at the definition of the puzzle widget (or whatever it's called). The widget does the thing I think you want to do, just it doesn't use model-view, but the idea remains. If a drag is started, the item gets removed from the widget, if a valid drop occurs, the item gets inserted in a new position. If an invalid drop occurs, the item gets inserted back into the place it was taken from. No matter where you actually drop the item (and by using a custom MIME type it assures that you won't make a valid drop outside the puzzle application).

  11. The following 2 users say thank you to wysota for this useful post:

    larry104 (21st July 2006), Micawber (26th May 2008)

  12. #11
    Join Date
    Jun 2006
    Location
    San Jose, CA
    Posts
    53
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Drag and drop between model views

    Qt Code:
    1. ... using a custom MIME type it assures ...
    To copy to clipboard, switch view to plain text mode 
    Yep, that does the trick to ensure that only the target is allowed to accept the drop. Unfortunately, rewriting startDrag is a little bit of work. Thanks again for the help.

  13. #12
    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: Drag and drop between model views

    Quote Originally Posted by larry104
    Unfortunately, rewriting startDrag is a little bit of work. Thanks again for the help.
    Copy and paste it from Qt sources and add the lines you need.

  14. #13
    Join Date
    Jun 2006
    Location
    San Jose, CA
    Posts
    53
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Drag and drop between model views

    Hmmm, that might be embarrissing for me (after all I'm QT beginner) but I get compile errors when I just copy it.

    Qt Code:
    1. void QAbstractItemView::startDrag(Qt::DropActions supportedActions)
    2. {
    3. QModelIndexList indexes = selectedIndexes();
    4. if (indexes.count() > 0) {
    5. // setup pixmap
    6. QRect rect = visualRect(indexes.at(0));
    7. QList<QRect> rects;
    8. for (int i = 0; i < indexes.count(); ++i) {
    9. rects.append(visualRect(indexes.at(i)));
    10. rect |= rects.at(i);
    11. }
    12. rect = rect.intersect(d->viewport->rect());
    13. QPixmap pixmap(rect.size());
    14. pixmap.fill(palette().base().color());
    15. QPainter painter(&pixmap);
    16. QStyleOptionViewItem option = viewOptions();
    17. option.state |= QStyle::State_Selected;
    18. for (int j = 0; j < indexes.count(); ++j) {
    19. option.rect = QRect(rects.at(j).topLeft() - rect.topLeft(),
    20. rects.at(j).size());
    21. itemDelegate()->paint(&painter, option, indexes.at(j));
    22. }
    23. painter.end();
    24. // create drag object
    25. QDrag *drag = new QDrag(this);
    26. drag->setPixmap(pixmap);
    27. drag->setMimeData(model()->mimeData(indexes));
    28. drag->setHotSpot(d->viewport->mapFromGlobal(QCursor::pos()) - rect.topLeft());
    29. if (drag->start(supportedActions) == Qt::MoveAction)
    30. d->removeSelectedRows();
    31. }
    32. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. ../../../qt/qt-4.1.4/include/QtGui/qtableview.h: In member function `virtual
    2. void MyTableView::startDrag(QFlags<Qt::DropAction>)':
    3. ../../../qt/qt-4.1.4/include/QtGui/qtableview.h:134: `QTableViewPrivate*
    4. QTableView::d_func()' is private
    5. mytableview.cpp:43: within this context
    6. mytableview.cpp:43: cannot convert `QTableViewPrivate*' to `
    7. QAbstractItemViewPrivate* const' in initialization
    8. mytableview.cpp:53: invalid use of undefined type `struct
    9. QAbstractItemViewPrivate'
    10. ../../../qt/qt-4.1.4/include/QtGui/qabstractitemview.h:41: forward declaration
    11. of `struct QAbstractItemViewPrivate'
    12. mytableview.cpp:69: invalid use of undefined type `struct
    13. QAbstractItemViewPrivate'
    14. ../../../qt/qt-4.1.4/include/QtGui/qabstractitemview.h:41: forward declaration
    15. of `struct QAbstractItemViewPrivate'
    16. mytableview.cpp:71: invalid use of undefined type `struct
    17. QAbstractItemViewPrivate'
    18. ../../../qt/qt-4.1.4/include/QtGui/qabstractitemview.h:41: forward declaration
    19. of `struct QAbstractItemViewPrivate'
    20. make: *** [mytableview.o] Error 1
    To copy to clipboard, switch view to plain text mode 

  15. #14
    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: Drag and drop between model views

    You can't use private components of Qt classes as they are not accessible, so you have to think a workaround for using Q_D and d->. It shouldn't be too hard as d->viewport should be available as viewport() and you can remove the selected rows without using the d->removeSelectedRows() call if you need that functionality. And when you won't be using "d" anymore, you can remove the Q_D() call.

  16. #15
    Join Date
    Jun 2006
    Location
    San Jose, CA
    Posts
    53
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Drag and drop between model views

    Works perfect now - thanks again so much for all the help.

  17. #16
    Join Date
    Sep 2007
    Posts
    29
    Thanks
    8

    Default Re: Drag and drop between model views

    Quote Originally Posted by wysota View Post
    QDrag::start returns an information if the drag was accepted and with which action. If it was dropped on an invalid target, it will return IgnoreAction, if it was dropped on a valid target but the drop was rejected, it will return IgnoreAction. If it was dropped on a valid target and the target did something with the data (no matter if the target is in the same application as the source or if it's a completely different program), it will return an action telling you what should you do with the data -- copy, move, link or ignore it.
    what could be the cause if the item was dropped on a valid target, but QDrag::exec (or start) still returns IgnoreAction?

    i'm creating a QDrag object in a custom item view in the startDrag(...) function like this:
    Qt Code:
    1. p_pDrag->setMimeData(p_pMimeData);
    2. p_pDrag->setHotSpot(QPoint());
    3. p_pDrag->setPixmap(p_Pixmap);
    4.  
    5. // always returns IGNORE?!
    6. Qt::DropAction p_DropAction = p_pDrag->exec(Qt::MoveAction | Qt::CopyAction);
    To copy to clipboard, switch view to plain text mode 

    the underlying model's (subclassed QStandardItemModel) flag function gives Qt::ItemIsDropEnabled for every index, supportedDropActions gives Qt::MoveAction | Qt::CopyAction.
    i overloaded dropEvent(...) for the view and QDropEvent::dropAction() is CopyAction
    i also set setDragEnabled and setAcceptDrops to true and setDragDropMode to DragDrop

    but still no luck
    d&d works fine btw, just the return value of exec is wrong...

  18. #17
    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: Drag and drop between model views

    Quote Originally Posted by maximAL View Post
    what could be the cause if the item was dropped on a valid target, but QDrag::exec (or start) still returns IgnoreAction?
    It probably means there is something wrong with your dropMimeData() implementation of the model where you drop the data. Did you remember to return true from the method?

  19. #18
    Join Date
    Sep 2007
    Posts
    29
    Thanks
    8

    Default Re: Drag and drop between model views

    yes, it definetly returns true

  20. #19
    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: Drag and drop between model views

    Can you show me the dropMimeData() implementation and the contents of supportedDragActions and supportedDropActions?

  21. The following user says thank you to wysota for this useful post:

    maximAL (19th January 2008)

  22. #20
    Join Date
    Sep 2007
    Posts
    29
    Thanks
    8

    Default Re: Drag and drop between model views

    oh boy, thats it. i didn't set the supported drag actions

Similar Threads

  1. Drag & drop with model/view (Qt4)
    By yogeshm02 in forum Qt Programming
    Replies: 16
    Last Post: 19th September 2011, 20:36
  2. Drag and drop outside the application
    By jpn in forum Newbie
    Replies: 7
    Last Post: 27th August 2006, 15:37
  3. Drag and drop revisited
    By Big Duck in forum Newbie
    Replies: 2
    Last Post: 30th June 2006, 16:41
  4. drag and drop with item views
    By castorvert in forum Qt Programming
    Replies: 14
    Last Post: 27th March 2006, 10:12
  5. Drag 'n Drop problem
    By kiker99 in forum Qt Programming
    Replies: 4
    Last Post: 16th January 2006, 16: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.