ДК
April 9, 2020, 1:31 p.m.

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

Do you like it? Share on social networks!

2
ДК
  • April 11, 2020, 10:18 p.m.
  • (edited)

всё никак не получается, хочу на выходных победить это дело. Сейчас поведение такое- могу взять строку, когда её дропаю создается в пустая строка ниже последней, ничего никуда не перемещается, всё остаётся на своих местах. Подскажите, какие методы обычно переопределяются для 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, есть там лишнее, знаю.

    ДК
    • April 12, 2020, 10:05 p.m.
    • (edited)

    вот так вставляется пустая строка, код мне подсказали. Только при перемещении строки она удаляется и пересоздаётся в БД. Наверное поэтому, вставляется уже пустая строка. Пока думаю поймать момент перед удалением информации и скопировать её с индексом вставки, а потом уже вызвать 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);

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

      Comments

      Only authorized users can post comments.
      Please, Log in or Sign up
      • Last comments
      • AK
        April 1, 2025, 11:41 a.m.
        Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
      • Evgenii Legotckoi
        March 9, 2025, 9:02 p.m.
        К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
      • VP
        March 9, 2025, 4:14 p.m.
        Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
      • ИМ
        Nov. 22, 2024, 9:51 p.m.
        Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
      • Evgenii Legotckoi
        Oct. 31, 2024, 11:37 p.m.
        Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup