tags:

views:

39

answers:

1

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.

A: 

Hi,

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.

Gnurou
Thank you for your answer. I have read that document but my implementation still doesn't dtrt. Perhaps you're right that I don't need to store anything in the internal pointer. I'm still working on this so I'll see what I can accomplish before I post a refinement to this question.
Ken Smith