Qt World Summit: Register Today!

Implementing Drag and Drop with QTreeView

  • I am trying to implement drag and drop for a TreeView using a model based off of QAbstractItemModel, taken from this example.

    As instructed here I have enabled my TreeView for drag&drop like so:


    I have set the appropriate flags in my model as well:

    Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
        if (!index.isValid())
            return 0;
        return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable | QAbstractItemModel::flags(index);

    And reimplemented QAbstractItemModel::supportedDropActions()

    Qt::DropActions TreeModel::supportedDropActions() const
        return Qt::CopyAction | Qt::MoveAction;

    I have also implemented DropMimeData() as follow, still no luck though.

    bool TreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent){
        if(!canDropMimeData(data, action, row, column, parent))
                return false;
        if (action == Qt::IgnoreAction)
            return true;
        int beginRow;
        if (row != -1)
            beginRow = row;
        else if (parent.isValid())
            beginRow = parent.row();
            beginRow = rowCount(QModelIndex());
       QModelIndex grandParent = parent.parent();
        insertRow(beginRow, grandParent);
        setData(parent.child(beginRow, 0), data);
        return true;

    The result is that I insert a brand new row into where the item is dropped. The old row isn't deleted and the new one contains no data.

    When hovering over another before dropping a box appears around a row but not a line between two rows indicating insertion. My model is trying to add the dropped item as a child: I found that the row and column passed to dropMimeData are both -1. While the parent's QModelIndex, points to the place where the item has been dropped. Do I need to set this "insert" behaviour somewhere?

    Perhaps my model is unsuitable?