Hi all,

I try to make DnD in QTableView. I made a sub-class of QAbstractTableModel.

Qt Code:
  1. #include "dragdroptableview.h"
  2.  
  3. DragDropTableView::DragDropTableView(QObject *parent) :
  4. {
  5. }
  6.  
  7. DragDropTableView::DragDropTableView(QList< QPair<QString, QString> > pairs, QObject *parent):
  8. {
  9. listOfPairs = pairs;
  10. }
  11.  
  12. int DragDropTableView::rowCount(const QModelIndex &parent) const
  13. {
  14. Q_UNUSED(parent);
  15. return listOfPairs.size();
  16. }
  17.  
  18. int DragDropTableView::columnCount(const QModelIndex &parent) const
  19. {
  20. Q_UNUSED(parent);
  21. return 2;
  22. }
  23.  
  24. QVariant DragDropTableView::data(const QModelIndex &index, int role) const
  25. {
  26. if (!index.isValid())
  27. return QVariant();
  28.  
  29. if (index.row() >= listOfPairs.size() || index.row() < 0)
  30. return QVariant();
  31.  
  32. if (role == Qt::DisplayRole) {
  33. QPair<QString, QString> pair = listOfPairs.at(index.row());
  34.  
  35. if (index.column() == 0)
  36. return pair.first;
  37. else if (index.column() == 1)
  38. return pair.second;
  39. }
  40. return QVariant();
  41. }
  42.  
  43. QVariant DragDropTableView::headerData(int section, Qt::Orientation orientation, int role) const
  44. {
  45. if (role != Qt::DisplayRole)
  46. return QVariant();
  47.  
  48. if (orientation == Qt::Horizontal) {
  49. switch (section) {
  50. case 0:
  51. return tr("Name");
  52.  
  53. case 1:
  54. return tr("Address");
  55.  
  56. default:
  57. return QVariant();
  58. }
  59. }
  60. return QVariant();
  61. }
  62.  
  63. bool DragDropTableView::insertRows(int position, int rows, const QModelIndex &index)
  64. {
  65. Q_UNUSED(index);
  66. beginInsertRows(QModelIndex(), position, position+rows-1);
  67.  
  68. for (int row=0; row < rows; row++) {
  69. QPair<QString, QString> pair(" ", " ");
  70. listOfPairs.insert(position, pair);
  71. }
  72.  
  73. endInsertRows();
  74. return true;
  75. }
  76.  
  77. bool DragDropTableView::removeRows(int position, int rows, const QModelIndex &index)
  78. {
  79. Q_UNUSED(index);
  80. beginRemoveRows(QModelIndex(), position, position+rows-1);
  81.  
  82. for (int row=0; row < rows; ++row) {
  83. listOfPairs.removeAt(position);
  84. }
  85.  
  86. endRemoveRows();
  87. return true;
  88. }
  89.  
  90. Qt::ItemFlags DragDropTableView::flags(const QModelIndex &index) const
  91. {
  92. if (!index.isValid())
  93. return Qt::ItemIsEnabled;
  94.  
  95. return QAbstractTableModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
  96. }
  97.  
  98. QStringList DragDropTableView::mimeTypes() const
  99. {
  100. QStringList types;
  101. types << "application/vnd.text.list";
  102. return types;
  103. }
  104.  
  105. QMimeData* DragDropTableView::mimeData(const QModelIndexList &indexes) const
  106. {
  107. QMimeData *mimeData = new QMimeData();
  108. QByteArray encodedData;
  109. QDataStream stream(&encodedData, QIODevice::WriteOnly);
  110. QModelIndex index;
  111. foreach (index, indexes)
  112. {
  113. if (index.isValid())
  114. {
  115. QString text;
  116. text = data(index, Qt::DisplayRole).toString();
  117. stream << text;
  118. }
  119. }
  120. mimeData->setData("application/vnd.text.list", encodedData);
  121. return mimeData;
  122. }
  123.  
  124. Qt::DropAction DragDropTableView::supportedDropActions()
  125. {
  126. return Qt::MoveAction;
  127. }
  128.  
  129. bool DragDropTableView::dropMimeData(const QMimeData *data,
  130. Qt::DropAction action,
  131. int row, int column,
  132. const QModelIndex &parent)
  133. {
  134. Q_UNUSED(column)
  135. if (!data->hasFormat("application/vnd.text.list"))
  136. {
  137. return false;
  138. }
  139. if (action == Qt::IgnoreAction)
  140. {
  141. return true;
  142. }
  143. int endRow = 0;
  144. if (!parent.isValid() && row < 0)
  145. {
  146. endRow = listOfPairs.count();
  147. }
  148. else if (!parent.isValid())
  149. {
  150. endRow = qMin(row, listOfPairs.count());
  151. }
  152. else
  153. {
  154. endRow = parent.row();
  155. }
  156.  
  157. QByteArray encodedData = data->data("application/vnd.text.list");
  158. QDataStream stream(&encodedData, QIODevice::ReadOnly);
  159.  
  160. while (!stream.atEnd())
  161. {
  162. QString first, second;
  163. stream >> first >> second;
  164. QPair <QString, QString> pair(first, second);
  165. beginInsertRows(QModelIndex(), endRow, endRow);
  166. listOfPairs.insert(endRow, pair);
  167. endInsertRows();
  168. endRow ++;
  169. }
  170. return true;
  171. }
To copy to clipboard, switch view to plain text mode 

When I DnD some item from first table to second the item is copied into second table, but not removed from first table.

Any ideas?