Drug Drop problems
Drug & Drop, QMimeData, Qt, QSqlTableModel
Привет. Есть делегат QSqlTableModel, на основе которого сделал Drug Drop.
Проблема в том, что перетаскивание работает корректно только тогда, когда я отображаю первую колонку - ID, если её скрыть, то поля съезжают и вместо перенесения строки отрабатывает вставка пустой, а копируемые данные меняются полями, иногда строку переносит нормально, но поля съезжают всё-равно.
Вот я и разбираюсь теперь в отладчике. Возникают вопросы, ответы на которые не нашел:
1)QMimeData копирует только отображенную информацию или также и из скрытых колонок? Просто в отладчике, что вижу: если отображенные поля есть все,
то имею все данные отображенных полей, данные одного скрытого, а еще данные от 2 скрытых нет.
Конкретно про колонку с ID, если я отображаю колонку с ID, то вижу, что данные с неё заносятся в QMimeData, если скрываю её, то этот ID в QMimeData не заносится.
2)Где можно почитать про ВСЕ форматы данных для QMimeData?
Я использую "application/x-qabstractitemmodeldatalist", а какие еще есть? Просто в доке такого формата вообще не нашел, а именно с ним работает.
Сам делегат:
SqlTableModelDrAndDr::SqlTableModelDrAndDr(QObject *parent, QSqlDatabase db) : QSqlTableModel(parent, db) { } Qt::DropActions SqlTableModelDrAndDr::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction; } Qt::ItemFlags SqlTableModelDrAndDr::flags(const QModelIndex &index) const { Qt::ItemFlags defaultFlags = QSqlTableModel::flags(index); if (index.isValid()) return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; else return Qt::ItemIsDropEnabled | defaultFlags; } QMimeData *SqlTableModelDrAndDr::mimeData(const QModelIndexList &indexes) const { QMimeData *mimeData = new QMimeData(); QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); stream << indexes[0].row(); foreach (const QModelIndex &index, indexes) { if (index.isValid()) { QString text = data(index, Qt::DisplayRole).toString(); stream << text; } } mimeData->setData("application/x-qabstractitemmodeldatalist", encodedData); return mimeData; } bool SqlTableModelDrAndDr::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const { Q_UNUSED(action) Q_UNUSED(row) Q_UNUSED(column) Q_UNUSED(parent) if (!data->hasFormat("application/x-qabstractitemmodeldatalist")) return false; return true; } bool SqlTableModelDrAndDr::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { if (!canDropMimeData(data, action, row, column, parent)) return false; if (action == Qt::IgnoreAction) return true; int beginRow; if (row != -1) beginRow = row; else if (parent.isValid()) beginRow = parent.row(); else beginRow = rowCount(QModelIndex()); QByteArray encodedData = data->data("application/x-qabstractitemmodeldatalist"); QDataStream stream(&encodedData, QIODevice::ReadOnly); QStringList newItems; int r; stream >> r; while (!stream.atEnd()) { QString text; stream >> text; newItems << text; } removeRow(r, QModelIndex()); submitAll(); if (beginRow > r) --beginRow; _finishRow = beginRow; insertRow(beginRow, QModelIndex()); int i = 0; foreach (const QString &text, newItems) { QModelIndex idx = index(beginRow, i++, QModelIndex()); setData(idx, text); } return true; }
Настройки вью и модели:
_reportsSQL->setSort(ReportDataBase::WEIGHT, Qt::SortOrder::AscendingOrder); ui->_reportsTableView->setEditTriggers(QTableView::NoEditTriggers); ui->_reportsTableView->setModel(_reportsSQL); /* * Установказа заголовков * */ for (int i = 0, j = 0; i < _reportsSQL->columnCount(); ++i, ++j) { _reportsSQL->setHeaderData(i, Qt::Horizontal, REPORTDATABASE->header(j).toUpper()); } if(!_roles.contains(Models::UserRole::ROLES::ADMIN)) ui->_reportsTableView->setColumnHidden(ReportDataBase::PATH, true); ui->_reportsTableView->setColumnHidden(ReportDataBase::ID,true); ui->_reportsTableView->setColumnHidden(ReportDataBase::SERVER_ID,true); ui->_reportsTableView->setColumnHidden(ReportDataBase::LAB_ID,true); ui->_reportsTableView->setColumnHidden(ReportDataBase::WEIGHT, true); ui->_reportsTableView->setItemDelegateForColumn(ReportDataBase::PATH, pathDelegate); ui->_reportsTableView->setSelectionBehavior(QAbstractItemView::SelectRows); ui->_reportsTableView->setSelectionMode(QAbstractItemView::SingleSelection); ui->_reportsTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); ui->_reportsTableView->horizontalHeader()->setStretchLastSection(true); ui->_reportsTableView->horizontalHeader()->moveSection(ReportDataBase::PATH, ReportDataBase::DESCRIPTION); ui->_reportsTableView->verticalHeader()->hide(); /* * For drag and drop * */ ui->_reportsTableView->setDragDropMode(QAbstractItemView::DragDropMode::InternalMove); ui->_reportsTableView->setDragEnabled(true); ui->_reportsTableView->setAcceptDrops(true); ui->_reportsTableView->setDropIndicatorShown(true); ui->_reportsTableView->viewport()->setAcceptDrops(true); ui->_reportsTableView->setDefaultDropAction(Qt::MoveAction); ui->_reportsTableView->setDragDropOverwriteMode(false); _reportsSQL->setEditStrategy(QSqlTableModel::OnManualSubmit);
В классе, управляющим QSqlDatabase, поля установлены верно, если бы это было не так, то, навреное, и на вью информация отображалась не в правильных колонках.
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.Do you like it? Share on social networks!
- Akiv Doros
- Nov. 11, 2024, 2:58 p.m.
C ++ - Test 004. Pointers, Arrays and Loops
- Result:50points,
- Rating points-4
- molni99
- Oct. 26, 2024, 1:37 a.m.
C ++ - Test 004. Pointers, Arrays and Loops
- Result:80points,
- Rating points4
- molni99
- Oct. 26, 2024, 1:29 a.m.
C ++ - Test 004. Pointers, Arrays and Loops
- Result:20points,
- Rating points-10
Добрый день.
mime data можно именовать как заблагоросудится. Просто есть стандартные типы данных, а есть кастомные. То есть разработчики сами решают как их называть.
Копирование со всех колонок скорее всего происходит из-за того, что у вас настроено построчное выделение.
По идее копировать должно только видимые поля, хотя при желании можно и переписать поведение. Но если учесть описание проблемы с первой колонкой и приложенный код, то становится ясно, что это ожидаемое поведение
В этом коде по логике забирается первая строка из QMimeData, если колонка скрыта, то естественно, что данные могут интерпретироваться как угодно. Может оказаться нужная строка, а может быть мусор.
Так что тут нужно продумывать логику и решать, что конкретно вам нужно.
Доброе утро! спасибо за ответ! а как настраивается поведение, чтобы копировались все поля всегда? тогда и проблем не будет со скрытыми колонками. Я имею ввиду в делегате что-то переделывать с data надо или просто есть какой-то флаг под эту задачу?
Я думаю, что вам этот метод нужно переписывать
То есть доделывать недостающие индексы, например, и по ним забирать данные.
благодорю!