自定义模型的拖动
便捷类的拖动实现很简单,今天我们介绍自己定义的ListModel模型如何实现拖动。在之前的ListModel项目基础上,我们先对View视图实现拖动操作.
//设置选择模式为单选listView.setSelectionMode(QAbstractItemView::ExtendedSelection);//设置可拖拽listView.setDragEnabled(true);//设置可拖放listView.setAcceptDrops(true);//设置显示拖放位置listView.setDropIndicatorShown(true);
对模型实现拖动
在ListModel添加声明
//编写拖动逻辑virtual QStringList mimeTypes() const;virtual QMimeData *mimeData(const QModelIndexList &indexes) const;virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action,int row, int column, const QModelIndex &parent);virtual Qt::DropActions supportedDropActions() const;
自定义一个类型,用来表示拖动导出的类型
//拖放时导出的类型
QStringList StringListModel:: mimeTypes() const{QStringList types;//自定义类型types << "application/zack.list";return types;
}
将拖动的数据放入mimedata中
QMimeData *StringListModel::mimeData(const QModelIndexList &indexes) const
{QMimeData * mimeData = new QMimeData();//字节数组QByteArray encodeData;QDataStream stream(&encodeData, QIODevice::WriteOnly);foreach(const QModelIndex& index, indexes){if(index.isValid()){QString text = data(index, Qt::DisplayRole).toString();stream << text;}}//将数据放入到QMimeData中mimeData->setData("application/zack.list", encodeData);return mimeData;}
将拖放的数据从mimedata中导出
bool StringListModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{//如果放入的动作是ignoreactionif(action == Qt::IgnoreAction){return true;}//如果数据的格式不是指定的格式,那么返回falseif(!data->hasFormat("application/zack.list")){return false;}//因为这里是列表, 只用一列, 所以列大于0时返回falseif(column > 0){return false;}//设置开始插入行int beginRow;if(row != -1){beginRow = row;}else if(parent.isValid()){beginRow = parent.row();}else {beginRow = rowCount(QModelIndex());}//将数据从QMimeData 中读取出来, 然后插入到模型中QByteArray encodeData = data->data("application/zack.list");//stream流QDataStream stream(&encodeData, QIODevice::ReadOnly);//统计插入的数据QStringList newItems;//统计插入的行数int rows = 0;while(!stream.atEnd()){QString text;stream >> text;newItems << text;++ rows;}//插入指定行数insertRows(beginRow, rows, QModelIndex());//批量修改行数数据foreach(const QString& text, newItems){QModelIndex idx = index(beginRow, 0, QModelIndex());setData(idx,text);beginRow++;}return true;
}
为了能让我们的item拖动,需要重新实现flags变量,使其支持拖放
Qt::ItemFlags StringListModel::flags(const QModelIndex& index) const{//索引无效可以接受放入操作if(!index.isValid())return Qt::ItemIsEnabled | Qt::ItemIsDropEnabled;//索引有效,可以接受拖拽和放入操作return QAbstractItemModel::flags(index) | Qt::ItemIsEditable| Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
}
然后我们设置支持的拖放动作为移动和复制
Qt::DropActions StringListModel::supportedDropActions() const
{//设置支持放入动作,允许copy和movereturn Qt::CopyAction | Qt::MoveAction;
}
拖动效果
源码链接
源码链接
https://gitee.com/secondtonone1/qt-learning-notes