#include "dragabletable.h" #include #include #include #include #include #include "Modules/GroupScreen/groupscreendelegate.h" DragableTable::DragableTable(QWidget *parent) : TableViewEx(parent) , m_UUID(QUuid::createUuid()) , m_bDragEnable(true) , m_nTargetRow(-1) , m_bIsUpon(false) { SetDragTargetRow(-1); setAcceptDrops(true); } //某行之下或之上 void DragableTable::SetDragTargetRow(int nRow, bool bIsUpOn) { if(!m_bDragEnable) return; GroupScreenDelegate *pDelegate = dynamic_cast(itemDelegate()); if(pDelegate == nullptr) return; pDelegate->SetDragTarget(nRow, bIsUpOn); m_nTargetRow = nRow; m_bIsUpon = bIsUpOn; update(); } void DragableTable::mouseMoveEvent(QMouseEvent *event) { QTableView::mouseMoveEvent(event); if(!m_bDragEnable) return; if(!m_indexPressed.isValid()) return; //启动Drag事件 QDrag *pDrag = new QDrag(this); QMimeData *pMimeData = new QMimeData(); pMimeData->setText(m_UUID.toString()); pDrag->setMimeData(pMimeData); pDrag->exec(Qt::MoveAction, Qt::CopyAction); m_indexPressed = QModelIndex(); SetDragTargetRow(-1); } void DragableTable::mousePressEvent(QMouseEvent *event) { QTableView::mousePressEvent(event); if(!m_bDragEnable) return; // 只允许左键按住 if(event->button() != Qt::LeftButton) return; // 根据触发鼠标位置获得QModelIndex m_indexPressed = indexAt(event->pos()); } void DragableTable::mouseReleaseEvent(QMouseEvent *event) { QTableView::mouseReleaseEvent(event); if(!m_bDragEnable) return; m_indexPressed = QModelIndex(); SetDragTargetRow(-1); } void DragableTable::dragEnterEvent(QDragEnterEvent *event) { if(!m_bDragEnable) { event->ignore(); } else { const QMimeData *pMimeData = event->mimeData(); if(!pMimeData || !pMimeData->hasText() || event->mimeData()->text() != m_UUID.toString()) { event->ignore(); } else { QModelIndex index = indexAt(event->pos()); int nRow = -1; // 如拖拽到表格的空白位置, 视为目标是最后一行之下 if(!index.isValid()) { nRow = model()->rowCount() - 1; SetDragTargetRow(nRow, false); } else { QRect indexRect = visualRect(index); int nRowHeight = verticalHeader()->sectionSize(index.row()); int nCenter = indexRect.top() + nRowHeight / 2; SetDragTargetRow(index.row(), event->pos().y() <= nCenter); } event->accept(); } } } void DragableTable::dragMoveEvent(QDragMoveEvent *event) { if(!m_bDragEnable) { event->ignore(); } else { QModelIndex index = indexAt(event->pos()); int nRow = -1; //如拖拽到表格的空白位置, 视为目标是最后一行之下 if(!index.isValid()) { nRow = model()->rowCount() - 1; SetDragTargetRow(nRow, false); } else { QRect indexRect = visualRect(index); int nRowHeight = verticalHeader()->sectionSize(index.row()); int nCenter = indexRect.top() + nRowHeight/2; SetDragTargetRow(index.row(), event->pos().y() <= nCenter); } event->accept(); } } void DragableTable::dropEvent(QDropEvent *event) { if(!m_bDragEnable) { event->ignore(); } else { int nSourceRow = m_indexPressed.row(); if(m_nTargetRow != -1 && nSourceRow != m_nTargetRow) { // 计算实际要插入到的行: 如果是插入到"之下", 则要加1; 如果把上方的行往下移, 则要减1 int nInsertedRow = m_nTargetRow + (m_bIsUpon ? 0 : 1) - ((nSourceRow > m_nTargetRow) ? 0 : 1); if(nSourceRow != nInsertedRow) { QStandardItemModel *pModel = dynamic_cast(model()); if(pModel) { QList targetRowItems = pModel->takeRow(nSourceRow); if(!targetRowItems.isEmpty()) pModel->insertRow(nInsertedRow, targetRowItems); selectRow(nInsertedRow); } // 发送信号 emit SignalDrop(nSourceRow, nInsertedRow); } } m_indexPressed = QModelIndex(); SetDragTargetRow(-1); event->acceptProposedAction(); } }