http://doc.qt.io/archives/4.6/model-view-dnd.html#inserting-dropped-data-into-a-model
一、View的设置
例如 QListView
QListView *listView = new QListView(this);
listView->setSelectionMode(QAbstractItemView::ExtendedSelection);
// SingleSelection(单选,不能取消选择), ContiguousSelection(可以多选,不能取消选择), ExtendedSelection(可以多选 shift,可以取消选择 ctrl),
// MultiSelection(可多选,可取消选择,但没有ctrl,shift快捷键)
listView->setDragEnabled(true);
listView->setAcceptDrops(true);
listView->setDropIndicatorShown(true);
二、Model的部分函数的重写
首先要继承对应的model,并重新实现以下5个方法
1. Qt::DropActions MyModel::supportedDropActions() const //model支持drag drop操作 { //支持copy和move操作,这些操作来自于Qt::DropActions return Qt::CopyAction | Qt::MoveAction; }
2. Qt::ItemFlags MyModel::flags(const QModelIndex &index) const // model中哪些items可以被drag,或可以接收drop { Qt::ItemFlags defaultFlags = QStringListModel::flags(index); if (index.isValid()) //index isValid,则index的row column非负,且index属于该model return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; else return Qt::ItemIsDropEnabled | defaultFlags; }
3. QStringList MyModel::mimeTypes() const //当items中的data从model导出时,他们被编译成一个或多个Mime类型 { QStringList types; types << "application/vnd.text.list"; //表示plain text,纯文本 return types; }
4. QMimeData MyModel::mimeData(const QModelIndexList &indexes) const //将items中的数据,编译成plain text并存储在QMimeData对象中 { QMimeData *mimeData = new QMimeData(); QByteArray encodedData; //存储“8 bit、以'\0'结尾的 字符串”,比const char*更方便; QDataStream stream(&encodedData, QIODevice::WriteOnly); //二进制的stream,100%的独立于操作系统。 foreach (QModelIndex index, indexes) { if (index.isValid()) { QString text = data(index, Qt::DisplayRole).toString(); stream << text; } } mimeData->setData("application/vnd.text.list", encodedData); return mimeData; }
5. bool MyModel::dropMimeData(const QMimeData *data,Qt::DropAction action, int row, int column, const QModelIndex &parent){ //将“拖放的数据(dropped data)”插入到Model中 if (action == Qt::IgnoreAction) return true; if (!data->hasFormat("application/vnd.text.list")) return false; if (column > 0) return false; // int beginRow; if (row != -1) beginRow = row; else if (parent.isValid()) beginRow = parent.row(); else beginRow = rowCount(QModelIndex()); // QByteArray encodedData = data->data("application/vnd.text.list"); QDataStream stream(&encodedData, QIODevice::ReadOnly); QStringList newItems; int rows = 0; while (!stream.atEnd()) { QString text; stream >> text; newItems << text; ++rows; } insertRows(beginRow, rows, QModelIndex()); foreach (QString text, newItems) { QModelIndex idx = index(beginRow, 0, QModelIndex()); setData(idx, text); beginRow++; } return true; }