dragabletable.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #include "dragabletable.h"
  2. #include <QDrag>
  3. #include <QMimeData>
  4. #include <QDebug>
  5. #include <QtEvents>
  6. #include <QHeaderView>
  7. #include "Modules/GroupScreen/groupscreendelegate.h"
  8. DragableTable::DragableTable(QWidget *parent)
  9. : TableViewEx(parent)
  10. , m_UUID(QUuid::createUuid())
  11. , m_bDragEnable(true)
  12. , m_nTargetRow(-1)
  13. , m_bIsUpon(false)
  14. {
  15. SetDragTargetRow(-1);
  16. setAcceptDrops(true);
  17. }
  18. //某行之下或之上
  19. void DragableTable::SetDragTargetRow(int nRow, bool bIsUpOn)
  20. {
  21. if(!m_bDragEnable) return;
  22. GroupScreenDelegate *pDelegate = dynamic_cast<GroupScreenDelegate*>(itemDelegate());
  23. if(pDelegate == nullptr) return;
  24. pDelegate->SetDragTarget(nRow, bIsUpOn);
  25. m_nTargetRow = nRow;
  26. m_bIsUpon = bIsUpOn;
  27. update();
  28. }
  29. void DragableTable::mouseMoveEvent(QMouseEvent *event)
  30. {
  31. QTableView::mouseMoveEvent(event);
  32. if(!m_bDragEnable) return;
  33. if(!m_indexPressed.isValid()) return;
  34. //启动Drag事件
  35. QDrag *pDrag = new QDrag(this);
  36. QMimeData *pMimeData = new QMimeData();
  37. pMimeData->setText(m_UUID.toString());
  38. pDrag->setMimeData(pMimeData);
  39. pDrag->exec(Qt::MoveAction, Qt::CopyAction);
  40. m_indexPressed = QModelIndex();
  41. SetDragTargetRow(-1);
  42. }
  43. void DragableTable::mousePressEvent(QMouseEvent *event)
  44. {
  45. QTableView::mousePressEvent(event);
  46. if(!m_bDragEnable) return;
  47. // 只允许左键按住
  48. if(event->button() != Qt::LeftButton) return;
  49. // 根据触发鼠标位置获得QModelIndex
  50. m_indexPressed = indexAt(event->pos());
  51. }
  52. void DragableTable::mouseReleaseEvent(QMouseEvent *event)
  53. {
  54. QTableView::mouseReleaseEvent(event);
  55. if(!m_bDragEnable) return;
  56. m_indexPressed = QModelIndex();
  57. SetDragTargetRow(-1);
  58. }
  59. void DragableTable::dragEnterEvent(QDragEnterEvent *event)
  60. {
  61. if(!m_bDragEnable)
  62. {
  63. event->ignore();
  64. }
  65. else
  66. {
  67. const QMimeData *pMimeData = event->mimeData();
  68. if(!pMimeData || !pMimeData->hasText() || event->mimeData()->text() != m_UUID.toString())
  69. {
  70. event->ignore();
  71. }
  72. else
  73. {
  74. QModelIndex index = indexAt(event->pos());
  75. int nRow = -1;
  76. // 如拖拽到表格的空白位置, 视为目标是最后一行之下
  77. if(!index.isValid())
  78. {
  79. nRow = model()->rowCount() - 1;
  80. SetDragTargetRow(nRow, false);
  81. }
  82. else
  83. {
  84. QRect indexRect = visualRect(index);
  85. int nRowHeight = verticalHeader()->sectionSize(index.row());
  86. int nCenter = indexRect.top() + nRowHeight / 2;
  87. SetDragTargetRow(index.row(), event->pos().y() <= nCenter);
  88. }
  89. event->accept();
  90. }
  91. }
  92. }
  93. void DragableTable::dragMoveEvent(QDragMoveEvent *event)
  94. {
  95. if(!m_bDragEnable)
  96. {
  97. event->ignore();
  98. }
  99. else
  100. {
  101. QModelIndex index = indexAt(event->pos());
  102. int nRow = -1;
  103. //如拖拽到表格的空白位置, 视为目标是最后一行之下
  104. if(!index.isValid())
  105. {
  106. nRow = model()->rowCount() - 1;
  107. SetDragTargetRow(nRow, false);
  108. }
  109. else
  110. {
  111. QRect indexRect = visualRect(index);
  112. int nRowHeight = verticalHeader()->sectionSize(index.row());
  113. int nCenter = indexRect.top() + nRowHeight/2;
  114. SetDragTargetRow(index.row(), event->pos().y() <= nCenter);
  115. }
  116. event->accept();
  117. }
  118. }
  119. void DragableTable::dropEvent(QDropEvent *event)
  120. {
  121. if(!m_bDragEnable)
  122. {
  123. event->ignore();
  124. }
  125. else
  126. {
  127. int nSourceRow = m_indexPressed.row();
  128. if(m_nTargetRow != -1 && nSourceRow != m_nTargetRow)
  129. {
  130. // 计算实际要插入到的行: 如果是插入到"之下", 则要加1; 如果把上方的行往下移, 则要减1
  131. int nInsertedRow = m_nTargetRow + (m_bIsUpon ? 0 : 1) - ((nSourceRow > m_nTargetRow) ? 0 : 1);
  132. if(nSourceRow != nInsertedRow)
  133. {
  134. QStandardItemModel *pModel = dynamic_cast<QStandardItemModel*>(model());
  135. if(pModel)
  136. {
  137. QList<QStandardItem*> targetRowItems = pModel->takeRow(nSourceRow);
  138. if(!targetRowItems.isEmpty()) pModel->insertRow(nInsertedRow, targetRowItems);
  139. selectRow(nInsertedRow);
  140. }
  141. // 发送信号
  142. emit SignalDrop(nSourceRow, nInsertedRow);
  143. }
  144. }
  145. m_indexPressed = QModelIndex();
  146. SetDragTargetRow(-1);
  147. event->acceptProposedAction();
  148. }
  149. }