ДК
9 апреля 2020 г. 13:31

QSqlTableModel + QTableView + Drag&Drop

QSqlDatabase, Drag and Drop, QSqlTableModel, Qt, QTableView

Привет. Делаю реализацию перемещения строк на QTableView с моделью QSqlTableModel. Буду в этой теме спрашивать нужное.
Пока такой вопрос при создании модели: как мне узнать rowCount?

  1. int SqlTableModelDrAndDr::rowCount(const QModelIndex &parent) const
  2. {
  3. return ??
  4. }

пока оставил

  1. return QSqlQueryModel::rowCount();
2

Вам это нравится? Поделитесь в социальных сетях!

2
ДК
  • 11 апреля 2020 г. 22:18
  • (ред.)

всё никак не получается, хочу на выходных победить это дело. Сейчас поведение такое- могу взять строку, когда её дропаю создается в пустая строка ниже последней, ничего никуда не перемещается, всё остаётся на своих местах. Подскажите, какие методы обычно переопределяются для dr&dr? Я уже обчитался литературы, документации, хотя QAbstr... модельные классы и так не плохо знаю. Сейчас решил что в моем случае хватает переопределения методов flags(...), supportedDropActions(); и dropMimeData(...) .

  1. Qt::ItemFlags SqlTableModelDrAndDr::flags(const QModelIndex &index) const
  2. {
  3. Qt::ItemFlags defaultFlags = QSqlTableModel::flags(index);
  4. if (index.isValid())
  5. return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
  6. else
  7. return Qt::ItemIsDropEnabled | defaultFlags;
  8. }
  9.  
  10. Qt::DropActions SqlTableModelDrAndDr::supportedDropActions() const
  11. {
  12. return Qt::MoveAction | Qt::CopyAction;
  13. }
  14.  
  15. bool SqlTableModelDrAndDr::dropMimeData(const QMimeData *data, Qt::DropAction action, int row,
  16. int column, const QModelIndex &parent)
  17. {
  18. if (!canDropMimeData(data, action, row, column, parent))
  19. return false;
  20. if (action == Qt::IgnoreAction)
  21. return true;
  22.  
  23. int beginRow;
  24.  
  25. if (row != -1)
  26. beginRow = row;
  27. else if (parent.isValid())
  28. beginRow = parent.row();
  29. else
  30. beginRow = rowCount(QModelIndex());
  31.  
  32. QByteArray encodedData = data->data("application/x-qabstractitemmodeldatalist");
  33. QDataStream stream(&encodedData, QIODevice::ReadOnly);
  34. QStringList newItems;
  35. int rows = 0;
  36.  
  37. while (!stream.atEnd()) {
  38. QString text;
  39. stream >> text;
  40. newItems << text;
  41. ++rows;
  42. }
  43.  
  44. rows = 1;
  45. qDebug() << "row insert:" << insertRows(beginRow, rows, QModelIndex());
  46. int i = 0;
  47. foreach (const QString &text, newItems) {
  48. QModelIndex idx = index(beginRow, i++, QModelIndex());
  49. setData(idx, text);
  50. beginRow++;
  51. }
  52. return true;
  53. }

на вьюхе так:

  1. ui->_reportsTableView->setDragDropMode(QAbstractItemView::DragDropMode::DragDrop);
  2. ui->_reportsTableView->setDragEnabled(true);
  3. ui->_reportsTableView->setAcceptDrops(true);
  4. ui->_reportsTableView->setDropIndicatorShown(true);
  5. ui->_reportsTableView->viewport()->setAcceptDrops(true);
  6. ui->_reportsTableView->setDefaultDropAction(Qt::MoveAction);
  7. ui->_reportsTableView->setDragDropOverwriteMode(false);

что надо добавить, какие методы еще переопределить или что не так написано? код тестовый в dropMimeData, есть там лишнее, знаю.

    ДК
    • 12 апреля 2020 г. 22:05
    • (ред.)

    вот так вставляется пустая строка, код мне подсказали. Только при перемещении строки она удаляется и пересоздаётся в БД. Наверное поэтому, вставляется уже пустая строка. Пока думаю поймать момент перед удалением информации и скопировать её с индексом вставки, а потом уже вызвать insertRows с этими данными.

    1. Qt::ItemFlags SqlTableModelDrAndDr::flags(const QModelIndex &index) const
    2. {
    3. Qt::ItemFlags defaultFlags = QSqlTableModel::flags(index);
    4. if (index.isValid())
    5. return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
    6. else
    7. return Qt::ItemIsDropEnabled | defaultFlags;
    8. }
    9.  
    10. Qt::DropActions SqlTableModelDrAndDr::supportedDropActions() const
    11. {
    12. // return Qt::MoveAction;
    13. return Qt::MoveAction | Qt::CopyAction;
    14. }
    15.  
    16. bool SqlTableModelDrAndDr::dropMimeData(const QMimeData *data, Qt::DropAction action, int row,
    17. int column, const QModelIndex &parent)
    18. {
    19. qDebug() << "dropMimeData" << action << row << column << parent;
    20. if (!canDropMimeData(data, action, row, column, parent))
    21. return false;
    22.  
    23. if (action == Qt::IgnoreAction)
    24. return true;
    25.  
    26. int beginRow;
    27.  
    28. if (row != -1)
    29. beginRow = row;
    30. else if (parent.isValid())
    31. beginRow = parent.row();
    32. else
    33. beginRow = rowCount(QModelIndex());
    34.  
    35. QByteArray encodedData = data->data("application/x-qabstractitemmodeldatalist");
    36. QDataStream stream(&encodedData, QIODevice::ReadOnly);
    37. QStringList newItems;
    38. int rows = 0;
    39.  
    40. int r;
    41. stream >> r;
    42.  
    43. while (!stream.atEnd()) {
    44. QString text;
    45. stream >> text;
    46. newItems << text;
    47. ++rows;
    48. }
    49. qDebug() << beginRow << newItems;
    50. qDebug() << "row remove:" << r << removeRows(r, 1, QModelIndex());
    51. submitAll();
    52. if (beginRow > r)
    53. --beginRow;
    54. rows = 1;
    55. qDebug() << "row insert:" << insertRows(beginRow, rows, QModelIndex());
    56. int i = 0;
    57. foreach (const QString &text, newItems) {
    58. QModelIndex idx = index(beginRow, i++, QModelIndex());
    59. setData(idx, text);
    60. //beginRow++;
    61. }
    62. return true;
    63. }
    1. ui->_reportsTableView->setDragDropMode(QAbstractItemView::DragDropMode::InternalMove);
    2. ui->_reportsTableView->setDragEnabled(true);
    3. ui->_reportsTableView->setAcceptDrops(true);
    4. ui->_reportsTableView->setDropIndicatorShown(true);
    5. ui->_reportsTableView->viewport()->setAcceptDrops(true);
    6. // ui->_reportsTableView->setDefaultDropAction(Qt::MoveAction);
    7. ui->_reportsTableView->setDragDropOverwriteMode(false);
    8. _reportsSQL->setEditStrategy(SqlTableModelDrAndDr::OnManualSubmit);

    *день спустя
    код выше рабочий, у меня просто в бд какие-то проблемы и есть одна колонка, скрыв которую, дроп работает через одно место, если её показывать, то всё отрабатывает, как надо.

      Комментарии

      Только авторизованные пользователи могут публиковать комментарии.
      Пожалуйста, авторизуйтесь или зарегистрируйтесь