Я хочу изменить набор изображений в qlistview. Я посмотрел на примеры, и я просто не могу заставить это работать. Когда я перетаскиваю изображение поверх другого, вызывается функция dropomimedata(), однако его «data-> hasImage()» всегда ложь. Когда я бросаю изображение в пустое место, почему-то dropmimedata() не запускается вообще.Qt AbstractItemModel переупорядочивание изображений
Моя модель должна выглядеть следующим образом:
Однако после перетаскивания в пустые пространства, это выглядит следующим образом:
И когда я перетащить изображение по другому ничего не меняется потому что hasImage всегда false. Что я делаю не так? Что мне не хватает?
#include "spritemodel.h"
#include <QDebug>
#include <QMimeData>
SpriteModel::SpriteModel() : QAbstractListModel()
{
}
void SpriteModel::setContents(QList<QPair<QImage, QOpenGLTexture*>> &newList)
{
beginInsertRows(QModelIndex(), 0, newList.size());
imageList = newList;
endInsertRows();
}
int SpriteModel::rowCount(const QModelIndex & parent) const
{
Q_UNUSED(parent);
return imageList.size();
}
QVariant SpriteModel::data(const QModelIndex & index, int role) const
{
if (role == Qt::DecorationRole)
return imageList[index.row()].first;
else if (role == Qt::DisplayRole)
return "";
else
return QVariant();
}
Qt::DropActions SpriteModel::supportedDropActions() const
{
return Qt::CopyAction | Qt::MoveAction;
}
Qt::ItemFlags SpriteModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
if (index.isValid())
return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
else
return Qt::ItemIsDropEnabled | defaultFlags;
}
bool SpriteModel::removeRows(int position, int rows, const QModelIndex &parent)
{
beginRemoveRows(QModelIndex(), position, position+rows-1);
for (int row = 0; row < rows; ++row) {
imageList.removeAt(position);
}
endRemoveRows();
return true;
}
bool SpriteModel::insertRows(int position, int rows, const QModelIndex &parent)
{
beginInsertRows(QModelIndex(), position, position+rows-1);
QImage img(imageList[0].first.width(), imageList[0].first.height(), imageList[0].first.format());
QOpenGLTexture *texture = new QOpenGLTexture(img);
for (int row = 0; row < rows; ++row) {
imageList.insert(position, qMakePair(img, texture));
}
endInsertRows();
return true;
}
bool SpriteModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
QImage img = value.value<QImage>();
QOpenGLTexture *texture = new QOpenGLTexture(img);
if (index.isValid() && role == Qt::EditRole) {
imageList.replace(index.row(), qMakePair(img, texture));
emit dataChanged(index, index);
return true;
}
return false;
}
QMimeData *SpriteModel::mimeData(const QModelIndexList &indexes) const
{
QMimeData *mimeData = new QMimeData();
QByteArray encodedData;
QDataStream stream(&encodedData, QIODevice::WriteOnly);
foreach (const QModelIndex &index, indexes) {
if (index.isValid()) {
QVariant img = data(index, Qt::DecorationRole);
stream << img;
}
}
mimeData->setData("image/png", encodedData);
return mimeData;
}
bool SpriteModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
if (data->hasImage()) {
qDebug() << "wut";
QImage img = qvariant_cast<QImage>(data->imageData());
QOpenGLTexture *texture = new QOpenGLTexture(img);
beginInsertRows(parent, 0, 1); // test
imageList.insert(row, qMakePair(img, texture));
endInsertRows();
emit dataChanged(QModelIndex(),QModelIndex());
return true;
}
return false;
}
Во-первых, спасибо, что ответили. Ваш пример работает. Однако некоторые из них не то, что мне нужно. Как это сделать, когда я перетаскиваю изображение поверх другого, он вставляет его перед мишенью вместо замены цели? (В идеале я хотел бы нажимать изображения, когда вы зависаете для предварительного просмотра, но не уверены, что это возможно). Также, когда я перетаскиваю изображение в пустое пространство, я хочу, чтобы он переместил его до конца, но я не могу показаться перетащить его туда. – Fundies
@ user3554386 Для меня, под Qt 5.4, он вставляет, а не замены. В любом случае, это не является полным, вам нужно добавить обработку для 'Qt :: DropAction'.В настоящее время он копирует изображения, а не перемещает их. Если вы хотите только поддерживать ходы, вы захотите установить его в представлении. –
У меня есть ser 'setDragDropMode (QListView :: InternalMove);' и 'setDefaultDropAction (Qt :: MoveAction);' но это не повлияло. Также я использую последние Qt – Fundies