效果演示

h文件
#ifndef MYTABLEVIEW_H #define MYTABLEVIEW_H
#include <QTableView> #include <QLabel> #include <QMouseEvent> #include <QStandardItemModel> #include <QScrollBar> #include <QApplication> #include <QDrag> #include <QMimeData> #include <QPainter> #include <QHeaderView>
class MyTableView : public QTableView { Q_OBJECT public: MyTableView(QWidget *parent = Q_NULLPTR);
void SetModel(QStandardItemModel *model);
signals: void sigRowChange(int from, int to);
protected: void mousePressEvent(QMouseEvent * event); void mouseMoveEvent(QMouseEvent *event);
void dragEnterEvent(QDragEnterEvent *event); void dragMoveEvent(QDragMoveEvent *event); void dropEvent(QDropEvent *event);
private: void DoDrag(); void ResetOrder(); void MoveRow(int from, int to);
private: QStandardItemModel *mModel; QLabel* mLabel; int mRowHeight;
bool mValidPress; int mRowFrom; int mRowTo;
QString mDragText; QPoint mDragPoint; QPoint mDragPointAtItem;
};
#endif
|
cpp文件
#include "MyTableView.h"
MyTableView::MyTableView(QWidget *parent) : QTableView(parent) { horizontalHeader()->hide(); verticalHeader()->hide(); verticalHeader()->setDefaultSectionSize(30); horizontalHeader()->setStretchLastSection(true); setEditTriggers(QTableView::NoEditTriggers); setSelectionBehavior(QTableView::SelectRows); setSelectionMode(QTableView::SingleSelection); setAlternatingRowColors(true); setShowGrid(false); setFocusPolicy(Qt::NoFocus); setStyleSheet("QTableView {border: 1px solid gray;background: #E8E8E8;}\ QTableView::item{color:black;}\ QTableView::item:selected{color:black;background: #63B8FF;}"); setColumnWidth(0, 40); setAcceptDrops(true);
mLabel = new QLabel(this); mLabel->setFixedHeight(2); mLabel->setGeometry(1, 0, width(), 2); mLabel->setStyleSheet("border: 1px solid #8B7500;"); mLabel->hide();
mModel = NULL; mRowHeight = 30; mValidPress = false; mRowFrom = 0; mRowTo = 0; }
void MyTableView::SetModel(QStandardItemModel *model) { mModel = model; QTableView::setModel(model); }
void MyTableView::mousePressEvent(QMouseEvent *e) { if (e->button() == Qt::LeftButton) { QModelIndex index = indexAt(e->pos()); if (index.isValid()) { int scrollValue = this->verticalScrollBar()->value(); int offsetValue = 0; bool isScrollBottom = (scrollValue > 0 && scrollValue >= this->verticalScrollBar()->maximum()); if (isScrollBottom) { offsetValue = (this->height() - horizontalHeader()->height()) % rowHeight(mRowFrom) - 3; }
mValidPress = true; mDragPoint = e->pos(); mDragText = mModel->item(index.row(), 1)->text();
if (isScrollBottom) { mDragPointAtItem = mDragPoint - QPoint(0,((index.row()-scrollValue)*mRowHeight)+(mRowHeight-offsetValue)); } else { mDragPointAtItem = mDragPoint - QPoint(0,(index.row()-scrollValue)*mRowHeight); }
mRowFrom = index.row(); } } QTableView::mousePressEvent(e); }
void MyTableView::mouseMoveEvent(QMouseEvent * e) { if (!mValidPress) { return; } if (!(e->buttons() & Qt::LeftButton)) return;
if ((e->pos() - mDragPoint).manhattanLength() < QApplication::startDragDistance()) return;
mLabel->show();
DoDrag();
mLabel->hide(); mValidPress = false; update(); }
void MyTableView::dragEnterEvent(QDragEnterEvent * e) { if (e->mimeData()->hasText()) { e->acceptProposedAction(); } else { e->ignore(); QTableView::dragEnterEvent(e); } }
void MyTableView::dragMoveEvent(QDragMoveEvent * e) { if (e->mimeData()->hasText()) { int scrollValue = this->verticalScrollBar()->value(); int offsetValue = 0; bool isScrollBottom = (scrollValue > 0 && scrollValue >= this->verticalScrollBar()->maximum()); if (isScrollBottom) { offsetValue = (this->height() - horizontalHeader()->height()) % rowHeight(mRowFrom) - 3; }
int nCurRow = 0; QModelIndex index = indexAt(e->pos()); if (index.isValid()) { if (e->pos().y() - ((index.row()-scrollValue)*mRowHeight+(mRowHeight-offsetValue))>= mRowHeight / 2) { nCurRow = index.row() + 1; } else { nCurRow = index.row(); } } else { nCurRow = mModel->rowCount(); }
{ mRowTo = nCurRow;
if (isScrollBottom) { mLabel->setGeometry(1, ((mRowTo-scrollValue)*mRowHeight+(mRowHeight-offsetValue)), width() - 2, 2); } else { mLabel->setGeometry(1, (mRowTo-scrollValue)*mRowHeight, width() - 2, 2); } }
e->acceptProposedAction(); return; }
e->ignore(); QTableView::dragMoveEvent(e); }
void MyTableView::dropEvent(QDropEvent * e) { if (e->mimeData()->hasText()) { if (mRowTo != mRowFrom) { MoveRow(mRowFrom, mRowTo); } e->acceptProposedAction(); return; }
e->ignore(); QTableView::dropEvent(e); }
void MyTableView::DoDrag() { QDrag *drag = new QDrag(this); QMimeData *mimeData = new QMimeData; mimeData->setText(mDragText); drag->setMimeData(mimeData);
QPixmap drag_img(width(), mRowHeight); drag_img.fill(QColor(255, 255, 255, 100)); QPainter painter(&drag_img); painter.setPen(QColor(0, 0, 0, 200)); painter.drawText(QRectF(40, 0, width(), mRowHeight), mDragText, QTextOption(Qt::AlignVCenter));
drag->setPixmap(drag_img); drag->setHotSpot(mDragPointAtItem);
if (drag->exec(Qt::MoveAction) == Qt::MoveAction) { } }
void MyTableView::ResetOrder() { for (int i = 0; i < mModel->rowCount(); i++) { mModel->item(i, 0)->setText(QString::number(i + 1)); } }
void MyTableView::MoveRow(int from, int to) { if (from == to) { return; } QStandardItem * item = mModel->item(from, 1); if (item) { QString strText = item->text();
QList<QStandardItem*> items; QStandardItem* item0 = new QStandardItem(""); QStandardItem* item1 = new QStandardItem(strText); items.append(item0); items.append(item1); item0->setTextAlignment(Qt::AlignCenter);
mModel->insertRow(to, items); if (from < to) { mModel->removeRow(from); selectRow(to - 1); } else { mModel->removeRow(from + 1); selectRow(to); } ResetOrder(); emit sigRowChange(mRowFrom, mRowTo);
}
}
|
在此基础上修改,没有了滚动条的问题
Qt可拖拽排序表格(类似QQ好友分组排序)
感谢博主无私分享