Drag and Drop in ItemView dependant on Item
-
Hello,
I have a QTreeView with a model where I want to be able to drag and drop Items of type A onto Items of type B, and also Items of type C onto items of type D.
I've implemented drag and drop for items of type A to B by returning
Qt::ItemIsDragEnabledflags
for A andQt::ItemIsDropEnabled
flags for B.However I do not know how I can switch the
Qt::ItemIsDropEnabled
flag depending on the item that is currently dragged around? What would be the right way to implement this? -
You should implement a method to change the
Qt::ItemIsDropEnabled
flag for an index in the model (e.gMyModel::setFlags(const QModelIndex&,Qt::ItemFlags)
basically the same asQStandardItem::setFlags
forQStandardItemModel
) then do something like this:class MyView : public QTreeView { Q_OBJECT Q_DISABLE_COPY(MyView) public: MyView(QWidget *parent = nullptr) : QTreeView (parent) {} protected: void dragMoveEvent(QDragMoveEvent *event) override{ const QModelIndex index = indexAt(event->pos()); const bool canBeDropped = checkIfItemDraggedCanBeDroppedOnIndex(index); // this depends on your logic const Qt::ItemFlags oldFlags = model()->flags(index); MyModel* mdl = nullptr; if(!canBeDropped && index.isValid() && (oldFlags & Qt::ItemIsDropEnabled)){ mdl = dynamic_cast<MyModel*>(model()); Q_ASSERT(mdl); mdl->setFlags(index,oldFlags & ~Qt::ItemIsDropEnabled); } QTreeView::dragMoveEvent(event); if(mdl) mdl->setFlags(index,oldFlags); } };
-
Yeah, I mean the source item.
Since I didn't want to mess around with the mime data I now ended up with another approach:
In the mimeData() method of my model I set a boolen flag on the item that is currently the one that is dragged around. Now in the flags() method I get the flagged item from the model and look what type it is and depending on that I can decide whether drops are enabled on the underlying item or not. This works fine, however it still looks like a bit of a hack.