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));

posted @ 2025-10-03 11:29  小城熊儿  阅读(11)  评论(0)    收藏  举报