You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

拖拽后更新QHeaderView模型的Qt表格撤销机制问题

QTableWidget表头拖拽的撤销机制视图异常问题

当前实现

我在QTableWidget中通过以下代码启用垂直表头的拖拽功能:
m_tableWidget->verticalHeader()->setSectionsMovable(true);

为给拖拽操作实现撤销机制,我已完成旧数据存储逻辑,现在通过连接QHeaderView::sectionMoved信号捕获拖拽动作,存储新数据并推入撤销栈:
connect(m_tableWidget->verticalHeader(), &QHeaderView::sectionMoved, this, &MyTableWidget::dragAndDrop);

对应的拖拽处理函数实现如下:

void
MyTableWidget::dragAndDrop(int logicalIndex, int oldVisualIndex, int newVisualIndex)
{
    // 获取存储在vector中的表格数据
    auto& tableData = oldVector;
    // 同步数据以反映拖拽变化
    auto synchronizedTableData = synchronize(oldVisualIndex, newVisualIndex);
    // 推入撤销栈
    m_undoStack->push(new Undo(synchronizedTableData, oldTableData));
}

撤销栈中的redo函数实现如下:

void
Undo::redo()
{
    tableWidget->setRowCount(synchronizedTableData.size());
    // 将同步后的vector数据应用到表格
    for (int i = 0; i < synchronizedTableData.size(); ++i) {
        for (int j = 0; j < synchronizedTableData.at(i).size(); ++j) {
                m_tableWidget->setItem(i, j, new QTableWidgetItem(synchronizedTableData.at(i).at(j).toString()));
            }
        }
    }

问题描述

目前核心问题是:垂直表头拖拽仅改变视图展示顺序,不会更新QTableWidget的模型数据,遍历表格内容时数据仍保持拖拽前的顺序。

当通过撤销栈的redo函数设置表格数据后,视图显示异常:比如将第二行拖拽到倒数第二行,预期显示顺序为1 3 4 5 2 6,但实际显示为1 4 5 2 3 6,看起来像是拖拽操作被执行了两次。但此时遍历表格模型数据是正确的,也就是模型状态正常,但视图没有正确更新。

我猜测问题根源是混淆了垂直表头的视图索引与模型索引,考虑过两种方向:一是在拖拽完成后同步更新表头对应的模型数据,二是在撤销栈更新模型后重新刷新视图,但不知道具体如何实现,也不确定当前整体方案是否存在问题,希望得到解决思路。

内容的提问来源于stack exchange,提问作者Bakefish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 16:55:22