Qt4:QAbstractTableModel拖放没有MIME

时间:2010-01-26 22:46:08

标签: user-interface qt qt4

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

为了帮助澄清一下,该应用程序是一个动画程序,有点像Adobe Flash。继承QAbstractTableModel的类具有QMap<int, FrameState>(带struct FrameState{QPointF pos; bool visible;})来保存关键帧。这个QMap的状态是我想要显示的并且让用户编辑。如果有可见的关键帧,我绘制一个绿色圆圈;如果有一个不可见的关键帧,我绘制一个红色圆圈;如果前面的关键帧是可见的,我绘制一条线,如果前一个关键帧不可见,则不绘制任何内容。我希望用户能够拖动关键帧来改变他们的QMap键。

谢谢!

1 个答案:

答案 0 :(得分:4)

您可以使用视图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;
}

在接收端,您可以退出QMap

,从而获得您的数据结构(例如QDataStream,如果您要使用的话)
QByteArray encodedData = yourMimeData->data( YOUR_MIME_TYPE );
QDataStream stream( &encodedData, QIODevice::ReadOnly );
QMap decodedMap;
stream >> decodedMap;