Qt4:QAbstractTableModel 拖放 w/o MIME

Posted

技术标签:

【中文标题】Qt4:QAbstractTableModel 拖放 w/o MIME【英文标题】:Qt4: QAbstractTableModel Drag and Drop w/o MIME 【发布时间】:2010-01-26 22:46:08 【问题描述】:

我有一个继承 QAbstractTableModel 的类,并在 QMap 中保存一些复杂的结构。 QVariant data(QModelIndex index, ...) 方法只返回一个枚举,它描述了自定义项委托应如何绘制单元格的内容。我想在这个模型中实现拖放功能,以便用户可以在 QMap 中重新排序这些结构,但不能完全理解 Qt 希望我如何做到这一点。我只需要查看拖放操作的源索引和目标索引,其余的我可以处理,但我在 QAbstractItemModel 中找到的最接近的是dropMimeData() 函数。 DropMimeData() 没有给我源索引,并要求我将数据转换为某种 MIME 类型(明文等),但绝对不是。我可以通过创建一个只包含源索引的 QMimeData 来解决这个问题,但我想真正学习使用 Qt,因为它应该被使用,我觉得我错过了一些东西。有什么想法吗?

只是为了澄清一点,该应用程序是一个动画程序,其行为类似于 Adob​​e Flash。继承 QAbstractTableModel 的类有一个QMap<int, FrameState>(和struct FrameStateQPointF pos; bool visible;)来保存关键帧。这个 QMap 的这种状态是我想要显示并让用户编辑的状态。如果有可见关键帧,我画一个绿色圆圈,如果有一个不可见关键帧,我画一个红色圆圈,如果前一个关键帧可见,我画一条线,如果前一个关键帧不可见,我什么也不画。我希望用户能够拖动关键帧来更改他们的 QMap 键。

谢谢!

【问题讨论】:

【参考方案1】:

您可以使用视图dragEnterEvent 来获取最初选择的索引:

void DropTreeView::dragEnterEvent(QDragEnterEvent *event)

    QTreeView::dragEnterEvent(event);

    const QItemSelectionModel * sm = selectionModel();
    if (!sm)
        return;

    dragStartIndicies = sm->selectedIndexes();

您需要使用 mime-types 进行拖放,但 C++ Qt 提供了一种很好的方法,使用 QDataStream

QMimeData *YourModel::mimeData( const QModelIndexList &indexes ) const

    QByteArray encodedData;
    QDataStream stream( &encodedData, QIODevice::WriteOnly );

    stream << yourQMap /* OR almost any Qt data structure */;

    QMimeData *mData = new QMimeData();
    mData->setData( YOUR_MIME_TYPE, encodedData );

    return mData;

在接收端,您可以从QDataStream 中取出您的数据结构(即QMap,如果这是您想要使用的):

QByteArray encodedData = yourMimeData->data( YOUR_MIME_TYPE );
QDataStream stream( &encodedData, QIODevice::ReadOnly );
QMap decodedMap;
stream >> decodedMap;

【讨论】:

@Boatzart - 我假设您知道拖放的基础知识,只需要一些细节,如果没有,请进一步询问。 是的,我只是想确保没有更直接的方法,例如 (onDragAndDrop(ModelIndex source, ModelIndex dest)) 嗯,看起来可能有更直接的方法。通过 dropMimeData 中的拖放操作检查默认 MIME 数据(如果我没有重载 mimeData() 函数),我看到格式列表包含“application/x-qabstractitemmodeldatalist”。我相信这个默认数据包含一个 QModelIndexList,但我不知道如何读取它。 它可能适合您的需求。查看 qabstractitemmodel.cpp,特别是 QAbstractItemModel::decodeData 函数。 dropMimeDatamimeData 方法也很有指导意义。 太好了,谢谢。我在这里提出了一个简明的问题并举例回答:***.com/questions/2151216/…

以上是关于Qt4:QAbstractTableModel 拖放 w/o MIME的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Qt4 中将项目添加到模型并获取新添加项目的索引

Qt 4.x:如何实现拖放到桌面或文件夹中?

Qt4是不是实现了窗口图标的拖放?

QAbstractTableModel:index() 与 createIndex()

QAbstractTableModel::header 数据和 QML TableView

如何过滤 QAbstractTableModel 模型