Important: Please read the Qt Code of Conduct -

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 and Qt::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.g MyModel::setFlags(const QModelIndex&,Qt::ItemFlags) basically the same as QStandardItem::setFlags for QStandardItemModel) then do something like this:

    class MyView : public QTreeView {
        MyView(QWidget *parent = nullptr) 
            : QTreeView (parent)
        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());
                mdl->setFlags(index,oldFlags & ~Qt::ItemIsDropEnabled);

  • Thanks, that brought me a step further, but I still don't get how I find the item that is currently drag and dropped inside checkIfItemDraggedCanBeDroppedOnIndex(index) because the results depends on the type of that item.

  • index is the model index of the destination item if what you don't know what the source item is then you can access its data as described here

  • 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.

Log in to reply