QTreeView drop not working
-
I have two
QTreeView
both using custom implementations ofQAbstractItemModel
. I want to be able to drag an item from oneQTreeView
and drop it into the otherQTreeView
. This means that oneQTreeView
only supports dragging and the other one only supports dropping.
The dragging part is working and my model successfully encodes the data as aQMimeData
object and I know from another place that it works. Also, I get the proper "dragging item" animation.
My problem starts with the dropping: I can't drop any item into the otherQTreeView
. When I drag an item into the view, I see the "nope, you cannot drop here" animation. However, I can see that in my modelQAbstractItemModel::canDropMimeData()
is being executed and I always return true. However, the correspondingQAbstractItemModel::dropMimeData()
never gets called (and the animation shows that I can't drop).In the
QTreeView
I did the following two things:QTreeView* dropTreeView = new QTreeView; dropTreeView->setModel(myModel); dropTreeView->setDragDropMode(QAbstractItemView::DropOnly); dropTreeView->setAcceptDrops(true);
However, no luck. The tree view keeps rejecting the drop.
Once I got very desperate I manually subclassed
QTreeView
and overloaded the correspondingQTreeView::dragEnterEvent()
,QTreeView::dropEvent()
and so on. In those, I simply useqDebug()
to output a message and then call the default implementation. This allows me to see that all the dragXxx() methods are executed but thedropEvent()
never.I'm totally lost here. Any ideas?
-
This issue is now resolved. It turned out to be a problem in the model: I forgot to tell the root (invalid parent) to accept drops too. This is done in the
QAbstractItemModel::flags()
implementation.
The incorrect version was:Qt::ItemFlags MyModel::flags(const QModelIndex& index) const { if (!index.isValid()) { return 0; } return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled; }
While this is how it should look like to allow drops in the root (to add new items without a parent):
Qt::ItemFlags MyModel::flags(const QModelIndex& index) const { if (!index.isValid()) { return Qt::ItemIsDropEnabled; // Allow drops in the top-level (no parent) } return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled; }