Results 1 to 4 of 4

Thread: Subclassing QTreeWidgetItem for Drag & Drop?

  1. #1
    Join Date
    Feb 2008
    Posts
    7
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Subclassing QTreeWidgetItem for Drag & Drop?

    Greetings all,
    Regular lurker, first time posting. I want to be able to allow drops only on certain items in a QTreeWidget. Is it possible to subclass QTreeWidgetItem to allow it to be a "drop target" for a drag & drop operation? The code below shows the approach I tried, but it doesn't work correctly: only the first MyTreeWidgetItem I add to the tree control accepts drops! The fact that this only 'sort of' works makes me suspect I'm bumping into a side effect of some of Qt's C++ magic. Is it possible to subclass QTreeWidgetItem to accept drops? Alternatively, if there is another way to achieve the goal of fine-grained control of which items can be "dropped on", I'd be happy to learn about that.

    Thanks!
    Paul Kerchen

    Platform/environment: Qt 4.3.3, MSVC 7.1, Windows XP

    Qt Code:
    1. class MyTreeWidgetItem : public QWidget, public QTreeWidgetItem
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. MyTreeWidgetItem( QTreeWidget* parent);
    7.  
    8. signals:
    9. void itemDropped( MyTreeWidgetItem* item, QWidget* source );
    10.  
    11. protected:
    12. void dragEnterEvent(QDragEnterEvent* event);
    13. void dragMoveEvent(QDragMoveEvent* event);
    14. void dropEvent(QDropEvent* event);
    15. };
    16.  
    17. MyTreeWidgetItem::MyTreeWidgetItem( TreeWidget* parent )
    18. : QWidget(parent)
    19. , QTreeWidgetItem( parent )
    20. {
    21. setAcceptDrops(true);
    22. }
    23.  
    24.  
    25.  
    26. void MyTreeWidgetItem::
    27. dragEnterEvent(QDragEnterEvent* event)
    28. {
    29. event->setDropAction(Qt::CopyAction);
    30. event->acceptProposedAction();
    31. }
    32.  
    33.  
    34. void MyTreeWidgetItem::
    35. dragMoveEvent(QDragMoveEvent* event)
    36. {
    37. event->setDropAction(Qt::CopyAction);
    38. event->acceptProposedAction();
    39. }
    40.  
    41.  
    42. void MyTreeWidgetItem::
    43. dropEvent(QDropEvent* event)
    44. {
    45. event->setDropAction(Qt::CopyAction);
    46. event->acceptProposedAction();
    47. emit itemDropped(this, event->source());
    48. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by kerchen; 24th April 2008 at 20:04. Reason: Added platform info

  2. #2
    Join Date
    Feb 2008
    Posts
    7
    Thanks
    2
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Subclassing QTreeWidgetItem for Drag & Drop?

    Well, I found another way to do what I need to do without having to subclass QTreeWidgetItem:

    Subclass QTreeWidget and reimplement dragEnterEvent() and dragMoveEvent() so that they check to see if the item that the event occurred over is an item that can accept the drop. For example:

    Qt Code:
    1. void MyTreeWidget::
    2. dragEnterEvent(QDragEnterEvent* event)
    3. {
    4. QTreeWidgetItem* item = itemAt(event->pos());
    5.  
    6. if ( itemAcceptsEvent(event,item) )
    7. event->setDropAction(Qt::CopyAction);
    8. else
    9. event->setDropAction(Qt::IgnoreAction);
    10. event->accept();
    11. }
    To copy to clipboard, switch view to plain text mode 

    A few important points:
    • Call accept() and not acceptProposedAction() if you're overriding the proposed action.
    • IgnoreAction must be one of the possible actions specified by the drag source when the drag was initiated. Otherwise, it defaults to CopyAction.


    Hopefully this saves someone a little time!

  3. #3
    Join Date
    May 2006
    Posts
    788
    Thanks
    49
    Thanked 48 Times in 46 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Subclassing QTreeWidgetItem for Drag & Drop?

    If you can read my code this QListWidget can drag drop multile items as icon.. and text
    from attribute hotels sauna bar, ecc..

    Qt Code:
    1. class IconScroller : public QListWidget
    2. {
    3. Q_OBJECT
    4. //
    5. public:
    6. IconScroller( bool enable = false , QWidget* parent = 0 )
    7. : QListWidget( parent )
    8. {
    9. enableout = enable;
    10. setSelectionMode ( QAbstractItemView::ExtendedSelection );
    11. setAcceptDrops(true);
    12. setDropIndicatorShown(false);
    13. if (enable) {
    14. setDragEnabled(true);
    15. }
    16. ///////setIconSize ( QSize(80,80));
    17. }
    18.  
    19. void mousePressEvent(QMouseEvent *event)
    20. {
    21. if (enableout) {
    22. QListWidgetItem *child = itemAt(event->pos());
    23. if (!child) {
    24. return;
    25. }
    26. /* IcoLine = hotel attribut icon mit beschreibung in 6 sprachen und
    27.   int kategorie int id + pixmap 30x30 */
    28. IcoLine Io = child->data(Qt::UserRole).value<IcoLine>();
    29.  
    30. QPixmap dragicon = Io.pix().scaledToWidth(Io.pix().width() * 3); /* zoom it */
    31. /* TabIcone liste von IcoLine */
    32. TabIcone dd;
    33. dd.all_lines.append(Io);
    34.  
    35. QList<QListWidgetItem *> tutti = selectedItems();
    36.  
    37. for (int i=0; i<tutti.size(); i++) {
    38. QListWidgetItem *pane = tutti[i];
    39. IcoLine Iter = pane->data(Qt::UserRole).value<IcoLine>();
    40. dd.all_lines.append(Iter);
    41. }
    42.  
    43. QString stream = SaveTabelicon(dd); /* QDataStream zu toBase64 fuer sql*/
    44. QMimeData *mimeData = new QMimeData;
    45. mimeData->setData("application/x-atticonhotel",stream.toUtf8());
    46.  
    47. QDrag *drag = new QDrag(this);
    48. drag->setMimeData(mimeData);
    49. drag->setPixmap(dragicon);
    50. ///////drag->setHotSpot(event->pos() - ????? ); //////
    51. /* make pixmap large and setHotSpot not need */
    52.  
    53. if (drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction) == Qt::MoveAction) {
    54. qDebug() << "### drag move it " << Io.id();
    55. }
    56.  
    57. }
    58.  
    59. QListWidget::mousePressEvent(event);
    60. }
    61. void dropEvent(QDropEvent *event)
    62. {
    63. ///////qDebug() << "### dropEvent";
    64. if (event->mimeData()->hasFormat("application/x-atticonhotel")) {
    65. QByteArray itemData = event->mimeData()->data("application/x-atticonhotel");
    66. //////////qDebug() << "### dropEvent entra siiiiiiiiiiii ";
    67. QString daten = QString::fromUtf8(itemData.data());
    68. TabIcone liste = OpenTabelicon(daten);
    69. emit AppendList(liste);
    70. event->accept();
    71.  
    72. } else {
    73. event->ignore();
    74. }
    75. }
    76.  
    77.  
    78.  
    79. void dragEnterEvent(QDragEnterEvent *event)
    80. {
    81. qDebug() << "### dragEnterEvent ";
    82.  
    83. if (event->mimeData()->hasFormat("application/x-atticonhotel")) {
    84. qDebug() << "### dragEnterEvent si ";
    85. event->acceptProposedAction();
    86. } else {
    87. event->ignore();
    88. }
    89. }
    90.  
    91. void dragMoveEvent(QDragMoveEvent *event)
    92. {
    93. qDebug() << "### dragMoveEvent ";
    94.  
    95. if (event->mimeData()->hasFormat("application/x-atticonhotel")) {
    96. qDebug() << "### dragMoveEvent si ";
    97. event->acceptProposedAction();
    98. } else {
    99. event->ignore();
    100. }
    101. }
    102. bool enableout;
    103. signals:
    104. void AppendList(TabIcone);
    105. public slots:
    106.  
    107. };
    To copy to clipboard, switch view to plain text mode 

  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: Subclassing QTreeWidgetItem for Drag & Drop?

    It is not required to reimplement any events to handle drops. You need to do three things. First make sure your item returns a ItemIsDropEnabled flag among its QListWidgetItem::flags(). Then you will possibly need to reimplement QListWidget::dropMimeData() to handle a drop. You'll probably want to reimplement QListWidget::mimeData() as well, to be able to start drags properly.

Similar Threads

  1. Drag & Drop QTreeWidgetItem with editors
    By Mad Max in forum Qt Programming
    Replies: 3
    Last Post: 25th January 2007, 09:09

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.