PySide2中注册到QML的Property更新后TableView未同步刷新问题
问题原因
1. Qt Property 缺少变更通知信号
Qt的元对象系统要求,如果你定义的属性需要在值变更时主动通知QML层更新,必须为该属性绑定通知信号,你的代码里两个地方不符合要求:
- 没有为
paramDs属性定义对应的变更信号 - 定义
Property时没有指定notify参数,值修改后不会主动告知QML刷新
2. TableModel的rows是静态赋值
你初始化TableModel.rows时,直接把backend.paramDs的当前值拷贝给了对应的value字段,这是一次性赋值,不是动态绑定。就算后续paramDs本身能发送变更通知,rows数组里的对应值也不会自动同步更新。
修正方案
第一步:修复Manager类的Property定义
给paramDs添加变更信号,修改set_ds方法在值变更时发射信号,定义Property时指定notify参数:
from PySide2.QtCore import QObject, Signal, Property, Slot class Manager(QObject): processResult = Signal(bool) # 新增paramDs变更的通知信号 paramDsChanged = Signal(str) def __init__(self): QObject.__init__(self) self.ds = "loading .." @Slot() def start_processing(self): self.set_ds("500") def read_ds(self): return self.ds def set_ds(self, val): if self.ds == val: return self.ds = val # 值变更后发射通知信号 self.paramDsChanged.emit(val) # 定义Property时添加notify参数绑定信号 paramDs = Property(str, read_ds, set_ds, notify=paramDsChanged)
第二步:修复QML侧的动态更新逻辑
你可以选择两种方案的任意一种:
- 方案1:监听属性变更手动更新模型
在TableView所在的QML组件里添加信号监听,收到属性变更信号后手动更新rows对应项的值,并通知模型刷新:
TableView { id:tb anchors.fill: parent columnSpacing: 1 rowSpacing: 1 clip: true // 新增监听backend的属性变更信号 Connections { target: backend function onParamDsChanged(newVal) { tb.model.rows[1].value = newVal // 通知模型对应单元格数据变更,触发delegate刷新 tb.model.dataChanged(tb.model.index(1, 1), tb.model.index(1, 1)) } } model: TableModel { TableModelColumn { display: "param_name" } TableModelColumn { display: "value" } rows: [ { "param_name": "Param", "value": "Value" }, { "param_name": "number of classes", "value": backend.paramDs } ] } delegate: Rectangle { implicitWidth: displayer.width + 50 <100 ? 100 :displayer.width+50 implicitHeight: 50 color : "#aa009688" Text { id:displayer text: display color : "white" anchors.centerIn: parent } } }
- 方案2:delegate中直接绑定属性
不需要修改rows,直接在delegate里判断如果是对应行就直接绑定backend.paramDs,天然支持动态更新:
delegate: Rectangle { implicitWidth: displayer.width + 50 <100 ? 100 :displayer.width+50 implicitHeight: 50 color : "#aa009688" Text { id:displayer // 对应行直接取backend的属性,自动跟踪变更 text: model.param_name === "number of classes" ? backend.paramDs : display color : "white" anchors.centerIn: parent } }
内容的提问来源于stack exchange,提问作者Nemo
相关产品推荐
相关产品推荐

