Results 1 to 2 of 2

Thread: QML Drag and Drop including reordering the C++ model

  1. #1
    Join Date
    Feb 2025
    Posts
    1
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows Android

    Lightbulb QML Drag and Drop including reordering the C++ model

    Hello everyone!
    Please help me figure out how to deal with drag and drop in QML with reordering data in the model.
    I have a model in C++. Drag and drop delegates are implemented in QML. When moving a delegate, the change must be saved in the model. At the same time, it should be possible to create copies of delegates immediately after the element from which the copy is created. Copying also works. However, there is a catch...

    For example, I have a list displayed:
    1
    2
    3
    I drag the 3rd element to the place of the second, I get
    1
    3
    2
    after which I want to create a copy of the first element and in QML I see this
    1
    3
    1
    2
    that is, the copy is inserted not after the copied element, but after the element that I dragged.
    In C++, the order of elements in QList is correct, but it does not correspond to what QML displays
    If you do not drag anything, then everything works correctly
    In this case, if you do beginResetModel and endResetModel in
    Qt Code:
    1. void ThingieListModel::move(int from, int to)
    To copy to clipboard, switch view to plain text mode 
    , then everything works correctly. But in my case, this solution does not work, since in the current project, delegates are loaded asynchronously using Loader and when beginResetModel is called, the UI displays how they are all reloaded

    Qt Code:
    1. /* Author: Remy van Elst, https://raymii.org
    2.  * License: GNU AGPLv3
    3.  */
    4. #include "ThingieListModel.h"
    5.  
    6. #include <QDebug>
    7.  
    8. ThingieListModel::ThingieListModel(QObject *parent) :
    9. {
    10. }
    11.  
    12. void ThingieListModel::updateFromVector(std::vector<Thingie*> newThingies)
    13. {
    14. qDebug() << "updateFromVector";
    15. beginResetModel();
    16. _thingies.clear();
    17. for (const auto &item : newThingies)
    18. {
    19. _thingies << item;
    20. }
    21. endResetModel();
    22. }
    23.  
    24. QHash<int, QByteArray> ThingieListModel::roleNames() const
    25. {
    26. QHash<int, QByteArray> roles;
    27. roles[NameRole] = "name";
    28. roles[ColorRole] = "color";
    29. roles[ModelIndexRole] = "modelIndex";
    30. return roles;
    31. }
    32.  
    33. QVariant ThingieListModel::data(const QModelIndex &index, int role) const
    34. {
    35. if (!index.isValid())
    36. {
    37. return QVariant();
    38. }
    39.  
    40. const Thingie *thingie = _thingies[index.row()];
    41. switch (role)
    42. {
    43. case NameRole:
    44. return thingie->name();
    45.  
    46. case ColorRole:
    47. return thingie->color();
    48.  
    49. case ModelIndexRole:
    50. if (std::find(_thingies.begin(), _thingies.end(), thingie) != _thingies.end()) {
    51. int d = std::distance(_thingies.begin(), std::find(_thingies.begin(), _thingies.end(), thingie));
    52. qDebug() << d;
    53. return d;
    54. } else {
    55. return -1;
    56. }
    57.  
    58. default:
    59. return QVariant();
    60. }
    61. }
    62.  
    63. int ThingieListModel::rowCount(const QModelIndex &) const
    64. {
    65. return _thingies.count();
    66. }
    67.  
    68.  
    69. void ThingieListModel::move(int from, int to)
    70. {
    71. qDebug() << "move " << from << ";" << to;
    72. if(from >= 0 && from < rowCount() && to >= 0 && to < rowCount() && from != to) {
    73. if(from == to - 1) { // Allow item moving to the bottom
    74. to = from++;
    75. }
    76.  
    77. // beginResetModel();
    78. beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
    79. qInfo() << "model move from: " << from << " to: " << to;
    80. _thingies.move(from, to);
    81. endMoveRows();
    82. // endResetModel();
    83.  
    84. }
    85. }
    86.  
    87. void ThingieListModel::createDublicate(int index)
    88. {
    89. int insertPosition = index + 1;
    90.  
    91. beginInsertRows(QModelIndex(), insertPosition, insertPosition);
    92. Thingie *newThingie = new Thingie{_thingies[index]->name(), static_cast<int>(_thingies.size()), this};
    93. newThingie->setColor(_thingies[index]->color());
    94. _thingies.insert(insertPosition, newThingie);
    95. endInsertRows();
    96. }
    97.  
    98. QString ThingieListModel::print()
    99. {
    100. qDebug() << "print";
    101. QString tmp;
    102. for(int i = 0; i < _thingies.size(); ++i) {
    103. tmp.append(QString::number(i));
    104. tmp.append(": ");
    105. tmp.append(_thingies.at(i)->name());
    106. tmp.append("; ");
    107. }
    108. return tmp;
    109. }
    To copy to clipboard, switch view to plain text mode 

    Here is a link to the full code: https://mega.nz/file/XQlQECqa#Lxhaaq...glXgZWYC6yyrv4
    Based on the article: https://raymii.org/s/tutorials/Qml_D...Cpp_Model.html

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,287
    Thanks
    310
    Thanked 868 Times in 855 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QML Drag and Drop including reordering the C++ model

    This sounds to me like an "off by one" error. If you are keeping the same iterator or row numbers without taking into account that you have added, removed, or rearranged rows, then your iterator or index becomes invalid once you have altered the first position.

    Sorry, I don't have time today to look at your complete code. I've been burned by this same kind of problem, so it seems a logical place for you to start looking.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Replies: 4
    Last Post: 18th April 2012, 19:11
  2. Drag & drop with model/view (Qt4)
    By yogeshm02 in forum Qt Programming
    Replies: 16
    Last Post: 19th September 2011, 21:36
  3. Drag and Drop for tree model
    By frank100 in forum Qt Programming
    Replies: 5
    Last Post: 8th December 2010, 20:21
  4. Drag and drop reordering in a QTableWidget
    By Lendrick in forum Qt Programming
    Replies: 1
    Last Post: 23rd November 2009, 00:19
  5. Drag and drop between model views
    By larry104 in forum Qt Programming
    Replies: 20
    Last Post: 19th January 2008, 17:09

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.