Home > Enterprise >  QTableView dropEvent never be called
QTableView dropEvent never be called

Time:09-17

I'm trying to use QTableView to display a list of remote files, and I want to support dragging files to table view, but I wasn't able to make it work.

class MyTableView: public QTableView {
    ...
    MyTableView(...) {
        setDragEnabled(true);
        setAcceptDrops(true);
        setDragDropMode(DragDrop);
        setDropIndicatorShown(true);
    }
protected:
    void dragEnterEvent(QDragEnterEvent *event) override {
        // This function is called
        const QMimeData* mimeData = event->mimeData();

        QStringList test = mimeData->formats();

        if (event->source() == nullptr) {
            if (mimeData->hasUrls()) {
                event->acceptProposedAction();
           }
        }
    }
    void dropEvent(QDropEvent *event) override {
       // This function is not called.
    }
    ....
}

class MyTableViewModel : public QAbstractTableModel {
    ...
    Qt::ItemFlags flags(const QModelIndex& index) const {
        if (!index.isValid())
            return Qt::NoItemFlags;

        Qt::ItemFlags flag = QAbstractItemModel::flags(index);
        flag |= Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
        return flag;
    }
    ...
}

dragEnterEvent is called, but dropEvent is never called.

Someone notes that I need to override the dragMoveEvent, but how should I implement it ?

Also, there is a guy who mentioned that QAbstractItemModel::canDropMimeData,dropMimeData, supportedDragActions, I tried to override these functions and simply returns true, but it still doesn't work.

Or are there any working demos/examples available? Or what's the right way to do that?

I googled a lot but found nothing useful. Thanks.

CodePudding user response:

Finally, I was able to make QTableView::dropEvent work as expected.

The official doc is here: Using Drag and Drop with Item Views. It's a long article but very useful.

Key pieces of code:

// Enable drop/drag in the constructor of MyTableView
setDragEnabled(true);
setAcceptDrops(true);
setDragDropMode(DragDrop);
setDropIndicatorShown(true);
// viewport()->setAcceptDrops(true); // it's not required although the doc mentioned it
// MyTableViewModel
Qt::ItemFlags MyTableViewModel::flags(const QModelIndex &index) const {
    Qt::ItemFlags flag = QAbstractItemModel::flags(index);

    if (index.isValid()) {
        return flag | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
    } else {
        return flag | Qt::ItemIsDropEnabled;
    }
}
Qt::DropActions MyTableViewModel::supportedDropActions() const {
    return Qt::CopyAction | Qt::MoveAction;
}
bool MyTableViewModel::canDropMimeData(const QMimeData* data, Qt::DropAction action, int row, int col, const QModelIndex& parent) const {
    return true; // just for simplicity
}
  • Related