实现QTableView的行拖拽,支持多行选择拖拽,也可根据需要稍作修改实现QTreeView、QListView等的拖拽效果。
拖拽类实现
继承 QTableView 实现几个拖拽相关的方法
TableView.h
#ifndef TableView_H
#define TableView_H
#include <QObject>
#include <QListView>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDragLeaveEvent>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QMimeData>
#include <QDrag>
#include <QDebug>
#include <QTableView>
class TableView : public QTableView
{
Q_OBJECT
public:
explicit TableView(QWidget *parent = nullptr);
bool isDraging() const {
return IsDraging;}
int offset() const {
return 12;}
int highlightedRow() const {
return curHighlightedRow;}
int dragRow() const {
return curDragRow;}
static QString myMimeType() {
return QStringLiteral("TableView/text-icon"); }
private:
//dropIndicator显示与消失
void updateDropIndicator(int row);
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
void dragLeaveEvent(QDragLeaveEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
void dropEvent(QDropEvent *event) override;
void startDrag(Qt::DropActions supportedActions) override;
private:
bool IsDraging = false;
//当前鼠标所在位置 行号
int curHighlightedRow = -2;
//被拖拽的行所在的位置
int oldHighlightedRow = -2;
//拖拽的行
int curDragRow = -1;
//当前鼠标放下所在行
int curInsertRow = -1;
//需要删除的旧行(行号)
QList<int> oldSelectRow;
//选中的拖拽行
QList<int> curDragRows;
};
bool compareBarData(const int &barAmount1, const int &barAmount2);
#endif // TableView_H
TableView.cpp
#include "TableView.h"
TableView::TableView(QWidget *parent) :
QTableView(parent)
{
setDragEnabled(true);
setAcceptDrops(true);
setEditTriggers(QAbstractItemView::NoEditTriggers);
this->setStyleSheet(
"QListView::Item{height:20px;}"
);
//列撑满整个表格
this->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
//去掉表格边框线
this->setShowGrid(false);
//整行选择
this->setSelectionBehavior(QAbstractItemView::SelectRows);
//按住ctrl多选
this->setSelectionMode(QAbstractItemView::ExtendedSelection);
}
void TableView::dragEnterEvent(QDragEnterEvent *event)
{
TableView *source = qobject_cast<TableView *>(event->source());
if (source && source == this) {
IsDraging = true; //IsDraging(标志位)判断是否正在拖拽
event->setDropAction(Qt::MoveAction);
event->accept();
}
}
void TableView::dragLeaveEvent(QDragLeaveEvent *event)
{
oldHighlightedRow = curHighlightedRow;
curHighlightedRow = -2;
//刷新以使dropIndicator消失,
updateDropIndicator(oldHighlightedRow);
IsDraging = false;
curInsertRow = -1;
event->accept();
}
//dropIndicator显示与消失
void TableView::updateDropIndicator(int row)
{
//这里用的是update(QModelIndex),这里也可以使用update(QRect),在表格所有列绘制分隔符
for (int updateColI = 0; updateColI < this->model()->columnCount();updateColI++) {
//刷新新区域使dropIndicator显示
update(model()->index(row, updateColI));
update(model()->index(row + 1, updateColI));
}
}
void TableView::dragMoveEvent(QDragMoveEvent *event)
{
TableView *source = qobject_cast<TableView *>(event->source());
if (source && source == this) {
oldHighlightedRow = curHighlightedRow;
curHighlightedRow = indexAt(event->pos() - QPoint(0, offset())).row();
//offset() = 9 = rowHeight / 2 - 1,其中 rowHeight 是行高
if(event->pos().y() >= offset()){
if(oldHighlightedRow != curHighlightedRow){
//刷新以使dropIndicator消失
updateDropIndicator(oldHighlightedRow);
//刷新新区域使dropIndicator显示
updateDropIndicator(curHighlightedRow
QTableView行拖拽实现:多行选择与定制分隔符

本文详细介绍了如何在QTableView中实现实时的行拖拽功能,支持多行选择,同时提供了自定义的拖拽指示器和分隔符样式委托。通过继承QTableView并实现相关方法,展示了如何扩展其拖拽操作到QListView和QTreeView等其他视图。
最低0.47元/天 解锁文章
9957

被折叠的 条评论
为什么被折叠?



