Qt4:从 QAbstractItemModel 读取默认 mimeData

发布于 2024-09-14 10:58:28 字数 1637 浏览 2 评论 0原文

我想做的与这个非常相似。除了我正在使用具有树结构的 QAbstractItemModel 并且对行和列感兴趣之外。事实上,在我的模型中,column 始终为 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 方式感兴趣。请告诉我您对这个想法的看法。

What I want to do is very similar to this. Except that I am working with a QAbstractItemModel that has a tree structure and am interested in more than just the row and column. In fact, in my model, column is always 0. But in order to implement drag and drop, I need to get the parent, children, and the opaque pointer that internalPointer() returns. Here is some relevant code. CTreeView extends 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.
    }
}

Any ideas? I only want to support drag and drop within the tree view so I'm thinking about storing the QModelIndexList of selectedIndexes() in a member variable of my subclass and just manipulating it directly in dropEvent(). That seems like cheating somehow so I'm still interested in the Qt way. Please let me know what you think of this idea.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

野心澎湃 2024-09-21 10:58:28

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

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

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

如果您告诉我们您如何创建索引,也许我们可以提供进一步的帮助。

First it looks like from your code that you are doing dnd the wrong way: you should not overload dropEvent in your view, but instead dropMimeData in your model. The following document explains how to do dnd with the model/view framework of Qt:

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

As for your specific problem, which is to access the internalPointer() of the dropped items. Storing the indexes in an index of your class is dangerous and error-prone. What you want to do is store the information you need in the mime data. I don't know what your use case is so I cannot guess what this useful data is - but if you just need the value of internalPointer (and can make sure this value will still be valid when the drop event is received), you can just store it, as you decide the format. For instance, if your data is referenced by a unique id somewhere (like the row id in a database), you can store this information and have a custom index(int rowid) method in your model that constructs a QModelIndex from this information. Normally the internalPointer of an index is set during its creation, so this would allow to fetch all the needed information.

If you tell us how you create your indexes maybe we can help further.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文