Я пытаюсь реализовать элементы перетаскивания (обычные/текстовые) из одного QListView в другой. Перетаскивание начинается хорошо (я даже могу перетаскивать элементы в другие приложения, которые принимают перетаскивание текста), но мой второй QListView по какой-то причине не принимает перетаскивания. Вот как настроено представление списка:
ui->lessonsListView->setAcceptDrops(true);
ui->lessonsListView->setDropIndicatorShown(true);
ui->lessonsListView->setDragDropMode(QAbstractItemView::DropOnly);
ui->lessonsListView->setDragDropOverwriteMode(true);
Прокси-модель для этого listView реализует следующие методы:
Qt::ItemFlags LessonsProxyModel::flags(const QModelIndex &index) const
{
qDebug() << __FUNCTION__;
return Qt::ItemIsDropEnabled | QSortFilterProxyModel::flags(index);
}
Qt::DropActions LessonsProxyModel::supportedDropActions() const
{
qDebug() << __FUNCTION__;
return Qt::MoveAction;
}
bool LessonsProxyModel::canDropMimeData(const QMimeData *data,
Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
qDebug() << __FUNCTION__;
Q_UNUSED(action);
Q_UNUSED(row);
Q_UNUSED(column);
if (!data->hasFormat("text/plain") || !parent.isValid())
return false;
return true;
}
bool LessonsProxyModel::dropMimeData(const QMimeData *data,
Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
qDebug() << __FUNCTION__;
if (!canDropMimeData(data, action, row, column, parent))
return false;
emit dataDropped(data, parent);
return true;
}
Из вывода приложения я вижу, что вызываются только supportedDropActions()
и flags()
. Ни canDropMimeData()
, ни dropMimeData()
никогда не звонили. Что я делаю неправильно? Любые подсказки будут оценены.
Спасибо!
ОТРЕДАКТИРОВАНО:
На всякий случай: ниже исходный код для listView и модели из тех, которые инициируются перетаскиванием: настройка listView:
ui->abonsListView->setDragEnabled(true);
код модели прокси:
Qt::ItemFlags AbonsProxyModel::flags(const QModelIndex &index) const
{
return Qt::ItemIsDragEnabled | QSortFilterProxyModel::flags(index);
}
Qt::DropActions AbonsProxyModel::supportedDragActions() const
{
qDebug() << __FUNCTION__;
return Qt::MoveAction;
}
QStringList AbonsProxyModel::mimeTypes() const
{
qDebug() << __FUNCTION__;
QStringList types;
types << "text/plain";
return types;
}
QMimeData *AbonsProxyModel::mimeData(const QModelIndexList &indexes) const
{
qDebug() << __FUNCTION__;
QMimeData *mimeData = new QMimeData();
foreach (const QModelIndex &index, indexes)
if (index.isValid())
{
mimeData->setText(data(index, AbonsModel::Id).toString());
qDebug() << __FUNCTION__;
return mimeData;
}
return mimeData;
}
dragEnterEvent
,dragMoveEvent
иdropEvent
подклассаQListView
. Ознакомьтесь с документацией и примеры - person Marcus   schedule 29.03.2016This document describes the basic drag and drop mechanism and outlines the approach used to enable it in custom controls.
И я просто следовал инструкциям по ссылкеUsing drag and drop with item views
. Также перетаскивание идеально подходит для другого представления списка без каких-либо подклассов: представления элементов уже поддерживают перетаскивание. - person Sergey Stasishin   schedule 29.03.2016QListView
в сочетании сQFileSystemModel
и файловым браузером (дельфин). Перетаскивание сQListView
на дельфин работает изумительно, а наоборот не принято. Поэтому я считаю, что вам придется настроитьdragEnterEvent
,dragMoveEvent
иdropEvent
для виджета, в котором вы собираетесь выполнить сброс. - person Marcus   schedule 29.03.2016QListView
работает нормально, вам не нужны подклассы. Покажи код, где ты настраиваешьQListView
, чтобы запустилось перетаскивание. - person Meefte   schedule 29.03.2016canDropMimeData()
, не объявленыvirtual
вQAbstractProxyModel
, и из-за этого неправильная функция называется:QAbstractProxyModel::canDropMimeData()
вместоcanDropMimeData()
моей модели. Вроде в этом причина, но как исправить или обойти не знаю... Вроде работает только сQAbstractItemModel
. - person Sergey Stasishin   schedule 29.03.2016QAbstractProxyModel
написано:virtual bool canDropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) const
но вqabstractproxymodel.h
я вижуbool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const Q_DECL_OVERRIDE;
. Я что-то пропустил? - person Sergey Stasishin   schedule 29.03.2016Q_DECL_OVERRIDE
. ЭтоC++11
специальное предложение.C++11
представил макрос препроцессора. В основном, чтобы проверить, действительно ли вы переопределяете участника или нет. Например, если вы хотите переопределитьvoid paintEvent( QPaintEvent* )
и в итоге набираетеvoid painterEvent( QPaintEvent )
, ваша функция никогда не будет вызвана. Если вы добавите voidpainterEvent( QPaintEvent ) Q_DECL_OVERRIDE
, будет выполнена проверка времени компиляции, и компилятор сообщит вам, что не определена такая функция, которую вы пытаетесь переопределить, тем самым экономя массу головной боли и много времени. - person Marcus   schedule 29.03.2016