Qt4:QAbstractTableModel 拖放无 MIME [英] Qt4: QAbstractTableModel Drag and Drop w/o MIME

查看:38
本文介绍了Qt4:QAbstractTableModel 拖放无 MIME的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a class which inherits QAbstractTableModel, and holds some complex structs in a QMap. The QVariant data(QModelIndex index, ...) method just returns an enum which describes how a custom item delegate should draw the contents of a cell. I would like to implement drag and drop functionality in this model so that users can reorder these structs in the QMap, but can't quite figure our how Qt would like me to do this. All I need is to see the source and destination indices of the drag/drop operation and I can take care of the rest, but the closest thing I've found in QAbstractItemModel is the dropMimeData() function. DropMimeData() doesn't give me the source index and requires me to convert the data into some MIME type (plaintext, etc.), which it is definitely not. I can hack my way through this by creating a QMimeData that just contains the source index, but I would like to really learn to use Qt as it's meant to be used, and I feel like I'm missing something. Any thoughts?

为了帮助澄清一下,该应用程序是一个动画程序,其行为有点像 Adob​​e Flash.继承 QAbstractTableModel 的类有一个 QMap(带有 struct FrameState{QPointF pos; bool visible;})来保存关键帧.这个 QMap 的状态是我想要显示并让用户编辑的状态.如果有一个可见的关键帧,我画一个绿色圆圈,如果有一个不可见的关键帧,我画一个红色圆圈,如果前一个关键帧可见,我画一条线,如果前一个关键帧不可见,我什么都不画.我希望用户能够拖动关键帧来更改他们的 QMap 键.

Just to help clarify a bit, the application is an animation program which acts sort of like Adobe Flash. The class which inherits QAbstractTableModel has a QMap<int, FrameState> (with struct FrameState{QPointF pos; bool visible;}) to hold keyframes. This state of this QMap is what I would like to display and have users edit. I draw a green circle if there is a visible key frame, a red circle if there is an invisible keyframe, a line if the previous keyframe was visible, and nothing if the previous keyframe was invisible. I would like users to be able to drag the keyframes around to change their QMap key.

谢谢!

推荐答案

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

You can use the views dragEnterEvent to get the indices that were selected initially:

void DropTreeView::dragEnterEvent(QDragEnterEvent *event)
{
    QTreeView::dragEnterEvent(event);

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

    dragStartIndicies = sm->selectedIndexes();
}

您需要使用 mime-types 进行拖放,但 C++ Qt 提供了一种使用 QDataStream:

You'll need to use the mime-types for the drag and drop, but C++ Qt provides a nice way to do that using 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,如果这是您想要使用的):

On the receiving end, you can get your data structure (i.e. QMap if that's what you want to use) back out of the QDataStream:

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

这篇关于Qt4:QAbstractTableModel 拖放无 MIME的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆