qt qtablewidget 行拖动(事件过滤器)
#include <QTableWidget>
class TablewidgetLineDropFilter : public QObject {
Q_OBJECT
public:
explicit TablewidgetLineDropFilter(QTableWidget* _box,QObject *parent = nullptr) : QObject(parent) {tablewidget=_box;}
bool eventFilter(QObject *obj, QEvent *event) override {
if(event->type() == QEvent::Drop){
int row_src,row_dst;
row_src = tablewidget->currentRow(); // 原行号 可加if
QDropEvent *dropEvent = static_cast<QDropEvent*>(event);
QTableWidgetItem *item = tablewidget->itemAt(dropEvent->pos()); // 获取落点的item
if(item !=nullptr){ // 判断是否为空
row_dst = item->row(); // 不为空 获取其行号
// 保证鼠标落下的位置 就是拖拽的一行最后所移动到的位置(考虑插入新行 移除原行的上下变化)
row_src = (row_src > row_dst? row_src + 1:row_src); // 如果src在dst的下方(行号大),后续插入dst会影响src的行号
row_dst = (row_src < row_dst? row_dst + 1:row_dst); // 如果src在dst的上方(行号小),后续移除src会影响dst的行号
tablewidget->insertRow(row_dst); // 插入一行
}
else{ // 落点没有item 说明拖动到了最下面
row_dst = tablewidget->rowCount();// 获取行总数
tablewidget->insertRow(row_dst); // 在最后新增一行
}
// 执行移动 并移除原行
for(int i = 0;i < tablewidget->columnCount();i++){ // 遍历列
tablewidget->setItem(row_dst,i,tablewidget->takeItem(row_src,i));// 每一列item的移动
}
tablewidget->removeRow(row_src); // 删除原行
// for(int i = 0;i < tablewidget->columnCount();i++){
// QTableWidgetItem* selectedItem = tablewidget->item(row_dst, i);
// tablewidget->setCurrentItem(selectedItem);
// }
return true;
}
return QObject::eventFilter(obj, event);
}
private:
QTableWidget* tablewidget;
};
应用
table->setDragEnabled(true); // 允许拖动
table->setAcceptDrops(true); // 接受放置
table->setDragDropMode(QAbstractItemView::InternalMove); // 内部移动模式
table->setSelectionBehavior(QAbstractItemView::SelectRows); // 整行选择
table->setDropIndicatorShown(true); // 显示放置位置指示
table->viewport()->installEventFilter(new TablewidgetLineDropFilter(table));

浙公网安备 33010602011771号