Qt4:从QAbstractItemModel读取默认mimeData

时间:2010-08-18 00:37:29

标签: c++ user-interface qt qt4

我想要做的与this非常相似。除了我正在使用具有树结构并且不仅仅对行和列感兴趣的QAbstractItemModel。事实上,在我的模型中,列始终为0.但是为了实现拖放,我需要获取internalPointer()返回的父项,子项和不透明指针。这是一些相关的代码。 CTreeView扩展了QTreeView。

void CTreeView::dragEnterEvent(QDragEnterEvent* event)
{
    if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
    {
        event->acceptProposedAction();
    }
}

void CTreeView::dropEvent(QDropEvent* event)
{
    const QMimeData* mime_data = event->mimeData();
    QByteArray encoded_data =
        mime_data->data("application/x-qabstractitemmodeldatalist");
    QDataStream stream(&encoded_data, QIODevice::ReadOnly);
    while (!stream.atEnd())
    {
        // I can do this.
        int row, column;
        stream >> row >> column;
        // But how do I construct the QModelIndex to get the parent, children,
        // and opaque pointer?

        // I have seen other advice that mentions doing this.
        QMap<int, QVariant> role_data_map;
        stream >> row >> col >> role_data_map;

        // Which allows you to do this.
        QList<int> keys = role_data_map.keys();
        BOOST_FOREACH(int key, keys)
        {
            QVariant variant = role_data_map[key];
            // use the variant
        }
        // But that only gets me part of the way there.
    }
}

有什么想法吗?我只想在树视图中支持拖放,所以我正在考虑将selectedIndexes()的QModelIndexList存储在我的子类的成员变量中,并直接在dropEvent()中对其进行操作。这似乎在某种程度上作弊,所以我仍然对Qt方式感兴趣。请让我知道你对这个想法的看法。

1 个答案:

答案 0 :(得分:0)

首先,从您的代码看起来,您正在以错误的方式执行:您不应在视图中重载dropEvent,而应在模型中使用dropMimeData。以下文档解释了如何使用Qt的模型/视图框架进行dnd:

http://doc.trolltech.com/latest/model-view-dnd.html

至于您的具体问题,即访问已删除项目的internalPointer()。将索引存储在类的索引中是危险且容易出错的。您要做的是将您需要的信息存储在mime数据中。我不知道你的用例是什么,所以我无法猜出这个有用的数据是什么 - 但如果你只需要internalPointer的值(并且可以确保在收到drop事件时该值仍然有效),你可以只需存储它,就像你决定格式一样。例如,如果您的数据在某处被唯一ID引用(如数据库中的行ID),则可以存储此信息并在模型中使用自定义索引(int rowid)方法从该信息构造QModelIndex。通常,索引的internalPointer在创建期间设置,因此这将允许获取所有需要的信息。

如果您告诉我们您如何创建索引,我们可以提供更多帮助。