Qt4: QAbstractTableModel Перетаскивание без MIME

Обновить

December 2018

Просмотры

1.7k раз

2

У меня есть класс , который наследует 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.

Спасибо!

rcv

1 ответы

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;