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

QDataWidgetMapper用QSortFilterProxyModel时QComboBox不更新模型

问题场景

使用QTableView绑定QSqlRelationalTableModel,搭配QDataWidgetMapper编辑表格当前活动行数值,核心实现代码如下:

model = QSqlRelationalTableModel(self, self.db)
model.setEditStrategy(QSqlTableModel.OnFieldChange)
model.setTable(table_name)

model.setRelation(i, relation_table, 'id', 'kurz')

proxy_model = QSortFilterProxyModel(self)
proxy_model.setSourceModel(model)
view.setModel(proxy_model)

cb.setModel(model.relationModel(i))
cb.setModelColumn(model.relationModel(i).fieldIndex('kurz'))

mapper = QDataWidgetMapper(self)
mapper.setModel(proxy_model)
mapper.setItemDelegate(QSqlRelationalDelegate(self))
mapper.addMapping(cb, i)

异常现象

  • 直接将QSqlRelationalTableModel实例设置为视图模型时,所有功能运行符合预期
  • 引入QSortFilterProxyModel作为视图绑定模型后,仅QComboBox绑定的外键字段存在同步异常:QComboBox可正常加载展示关联表数据,但控件内修改的选中值无法同步更新到视图;QLineEdit、日期选择控件等其他控件绑定的普通字段均能正常同步更新
  • 查阅官方文档未找到该问题的相关说明,需确认配置流程是否遗漏必要步骤。
根因分析

原生QSqlRelationalDelegate的提交逻辑仅适配直接绑定QSqlRelationalTableModel的场景:当QDataWidgetMapper绑定的模型是QSortFilterProxyModel时,委托拿到的模型索引属于代理模型层,原生委托没有做代理索引到源关系模型索引的映射,外键字段的特殊提交逻辑无法命中源模型的关联字段配置,最终导致QComboBox的修改无法落库同步;普通字段不需要走外键关联的特殊提交逻辑,因此不受代理层影响。

修复方案

自定义继承QSqlRelationalDelegate的委托类,重写setModelData方法,在提交数据前将代理模型索引映射为源QSqlRelationalTableModel的对应索引,再调用父类的提交逻辑即可:

class MapperRelationalDelegate(QSqlRelationalDelegate):
    def setModelData(self, editor, model, index):
        # 映射代理索引到源关系模型索引
        source_index = model.mapToSource(index)
        source_model = model.sourceModel()
        super().setModelData(editor, source_model, source_index)

将QDataWidgetMapper绑定的委托替换为上述自定义类的实例:

mapper.setItemDelegate(MapperRelationalDelegate(self))

替换后QComboBox的修改即可正常同步到视图与源模型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:33:09