Qt4: QAbstractTableModel Перетаскивание без MIME - PullRequest
2 голосов
/ 27 января 2010

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

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

Спасибо!

1 Ответ

4 голосов
/ 27 января 2010

Вы можете использовать представления 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...