2010-01-26 2 views
2

У меня есть класс, который наследует QAbstractTableModel и содержит некоторые сложные структуры в QMap. Метод QVariant data(QModelIndex index, ...) просто возвращает перечисление, которое описывает, как делегат пользовательского элемента должен рисовать содержимое ячейки. Я хотел бы реализовать функции перетаскивания в этой модели, чтобы пользователи могли переупорядочить эти структуры в QMap, но не могут точно понять, как Qt хотел бы, чтобы я сделал это. Все, что мне нужно, это увидеть исходные и целевые индексы операции перетаскивания/перетаскивания, и я могу позаботиться об остальном, но ближайшая вещь, которую я нашел в QAbstractItemModel, - это функция dropMimeData(). DropMimeData() не дает мне индекс источника и требует, чтобы я преобразовал данные в некоторый тип MIME (открытый текст и т. Д.), Что определенно не так. Я могу пробиться через это, создав QMimeData, которая просто содержит исходный индекс, но я бы хотел научиться использовать Qt, поскольку он предназначен для использования, и я чувствую, что что-то упускаю. Есть предположения?Qt4: QAbstractTableModel Drag and Drop без MIME

Просто, чтобы помочь немного прояснить, приложение представляет собой анимационную программу, которая действует как Adobe Flash. Класс, который наследует QAbstractTableModel, имеет QMap<int, FrameState>struct FrameState{QPointF pos; bool visible;}) для хранения ключевых кадров. Это состояние этого QMap - это то, что я хотел бы отображать и редактировать пользователя. Я рисую зеленый круг, если есть видимый ключевой фрейм, красный круг, если есть невидимый ключевой кадр, строка, если предыдущий ключевой кадр был виден, и ничего, если предыдущий ключевой кадр был невидимым. Я бы хотел, чтобы пользователи могли перетаскивать ключевые кадры для изменения своего ключа QMap.

Спасибо!

ответ

4

Вы можете использовать виды dragEnterEvent, чтобы получить показатели, которые были выбраны изначально:

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

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

    dragStartIndicies = sm->selectedIndexes(); 
} 

Вы должны будете использовать MIME-тип для перетаскивания, но 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; 
+0

@Boatzart - Я предполагаю, что вы знаете основы перетаскивания и просто необходимы некоторые особенности, если нет, спросите далее. –

+0

Yup, я просто хотел убедиться, что не было более простого способа, например (onDragAndDrop (источник ModelIndex, ModelIndex dest)) – rcv

+0

Хм, похоже, может быть несколько более простой способ. При проверке данных MIME по умолчанию (если я не перегружаю функцию mimeData()) из операции перетаскивания в dropMimeData, я вижу, что в списке форматов содержится «application/x-qabstractitemmodeldatalist». Я считаю, что данные по умолчанию содержат QModelIndexList, но я не могу понять, как его читать. – rcv