Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

MyModel::dropMimeData() not working



  • Guys,
    Maybe you can see something I'm missing. My goal is to drag data from one view to other, with custom mime type; but dropMimeData in the target model is never called. I'm pretty sure I've setup everything required.

    Well, fist views:

    void MainWindow::setDragnDrop(QAbstractItemView *view, bool enable, QAbstractItemView::DragDropMode mode)
    {
        view->setDragEnabled(enable);    
        view->setAcceptDrops(enable);
        view->viewport()->setAcceptDrops(enable);//I tried both
        view->setDropIndicatorShown(enable);
        view->setDragDropMode(mode);
    }
    

    calling in MainWindow constructor:

        setDragnDrop(ui->targetTreeView, true, QAbstractItemView::DragDrop);
        setDragnDrop(ui->sourceFilesList, true, QAbstractItemView::DragOnly);
    

    so setting views for drag'n'drop - CHECK

    Now the source model (descendant of QFileSystemModel) reimplementations:

        Qt::ItemFlags flags(const QModelIndex &index) const override;
        Qt::DropActions supportedDragActions() const override;
        QStringList mimeTypes() const override;
        QMimeData* mimeData(const QModelIndexList &indexes) const override;
    

    and bodies:

    Qt::ItemFlags PackagesModel::flags(const QModelIndex &index) const
    {
        auto defaultFlags = QFileSystemModel::flags(index);
    
        if (index.isValid())
        {
            return defaultFlags | Qt::ItemIsDragEnabled;
        }
    
        return defaultFlags;
    }
    
    Qt::DropActions PackagesModel::supportedDragActions() const
    {
        return Qt::CopyAction | Qt::LinkAction;
    }
    
    QStringList PackagesModel::mimeTypes() const
    {
        QStringList types;
        types.append(DragNDropData::mimeType);
        return types;
    }
    
    QMimeData* PackagesModel::mimeData(const QModelIndexList &indexes) const
    {
        QMimeData *data = new QMimeData;
    
        for (const QModelIndex &index : indexes)
        {
            //namespace DragNDropData { static const QString mimeType = "TerminalPackage"; }
            data->setData(DragNDropData::mimeType, fileInfo(index).absoluteFilePath().toUtf8());
        }
    
        return data;
    }
    

    required implementations in source model - CHECK

    And last, target model (descendand of QFileSystemModel) have reimplemented:

        Qt::DropActions supportedDropActions() const override;
        QStringList mimeTypes() const override;
        bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override;
        bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
    

    bodies:

    Qt::DropActions NavigationModel::supportedDropActions() const
    {
        return Qt::LinkAction | Qt::CopyAction;
    }
    
    QStringList NavigationModel::mimeTypes() const
    {
        QStringList types;
        types.append(DragNDropData::mimeType);
        return types;
    }
    
    #include <QDebug>
    bool NavigationModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
    {
        if (data->hasFormat(DragNDropData::mimeType) && parent.isValid() && action & (Qt::LinkAction | Qt::CopyAction))
        {
            qDebug() << "drop may be preformed";//this message shows up
            return true;
        }
    
        return false;
    }
    
    bool NavigationModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
    {
        if (!canDropMimeData(data, action, row, column, parent))
        {
            return false;
        }
    
        QString path(data->data(DragNDropData::mimeType));
    
        qDebug() << "drop detected - path: " << path << ", action: " << action << ", row: " << row << ", column: " << column << ", parent: " << parent;
        return true;
    }
    

    required implementations in target model - CHECK

    So dammit what else is needed to make it work??



  • Hah, after posting the thread, and taking a look at it I've spotted what was missing - target model requires flags() to be reimplemented:

    Qt::ItemFlags NavigationModel::flags(const QModelIndex &index) const
    {
        auto defaultFlags = QFileSystemModel::flags(index);
    
        if (index.isValid())
        {
            //pozwól na przeciąganie prawidłowych indeksów
            return defaultFlags | Qt::ItemIsDropEnabled;
        }
    
        return defaultFlags;
    }
    

    with that change everything works like charm.



  • Hah, after posting the thread, and taking a look at it I've spotted what was missing - target model requires flags() to be reimplemented:

    Qt::ItemFlags NavigationModel::flags(const QModelIndex &index) const
    {
        auto defaultFlags = QFileSystemModel::flags(index);
    
        if (index.isValid())
        {
            //pozwól na przeciąganie prawidłowych indeksów
            return defaultFlags | Qt::ItemIsDropEnabled;
        }
    
        return defaultFlags;
    }
    

    with that change everything works like charm.


Log in to reply