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

使用beginResetModel刷新模型时如何保留TreeView选中状态?

解决QSortFilterProxyModel重置模型后保留选中状态的方案

1. 保存选中项的唯一标识(而非代理索引)

不要直接保存QSortFilterProxyModel的索引——重置模型后这些索引会完全失效。转而保存源模型(QAbstractItemModel)中项的可靠唯一标识,常见方案有三种:

  • 项自带的业务ID字段(如果模型数据中包含)
  • 源模型的持久化索引(QPersistentModelIndex),需先把代理索引转换为源模型索引再创建
  • 项的层级路径(比如从根节点到当前项的文本/ID序列)

示例代码(用持久化索引保存):

// 重置模型前保存选中状态
QList<QPersistentModelIndex> selectedSourceIndexes;
const auto selectedProxyIndexes = treeView->selectionModel()->selectedIndexes();
for (const auto& proxyIdx : selectedProxyIndexes) {
    if (proxyIdx.isValid()) {
        auto sourceIdx = proxyModel->mapToSource(proxyIdx);
        selectedSourceIndexes.append(QPersistentModelIndex(sourceIdx));
    }
}

2. 执行模型重置操作

正常调用beginResetModel()和endResetModel()完成源模型的数据更新:

sourceModel->beginResetModel();
// 此处执行你的数据刷新逻辑
sourceModel->endResetModel();

3. 重置后恢复选中状态

将保存的源模型标识转换回代理模型的有效索引,再恢复选中状态:

// 恢复选中状态
QItemSelection selection;
for (const auto& persistentSourceIdx : selectedSourceIndexes) {
    if (persistentSourceIdx.isValid()) {
        auto proxyIdx = proxyModel->mapFromSource(persistentSourceIdx);
        if (proxyIdx.isValid()) {
            selection.select(proxyIdx, proxyIdx);
        }
    }
}
treeView->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect);

额外注意事项

  • 如果用ID或路径作为标识,需要在源模型中实现对应查找方法,根据标识定位到源模型索引后再转换为代理索引。
  • 确保源模型更新后,目标项仍然存在(若项已被删除,自然无法恢复选中)。
  • 若树结构有新增/删除父节点的变化,路径标识可能失效,优先使用持久化索引或业务唯一ID。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 04:12:00