PySide6中TableView重置模型时编辑单元格触发编辑器归属错误
解决PySide6 TableView编辑时的
QAbstractItemView::closeEditor错误 问题现象
编辑TableView单元格时,控制台输出以下错误:
QAbstractItemView::closeEditor called with an editor that does not belong to this view
QAbstractItemView::commitData called with an editor that does not belong to this view
QAbstractItemView::closeEditor called with an editor that does not belong to this view
问题原因
你的代码逻辑存在两个核心问题:
- 编辑器与模型状态脱节:当单元格处于编辑状态时,TableView会创建并持有一个编辑器实例。此时调用
setTableData中的beginResetModel()和endResetModel()会完全重置模型,视图会销毁所有旧数据项并重新构建。但编辑器仍绑定着旧的索引对象,导致后续编辑器提交/关闭操作时,视图识别到该编辑器不属于当前模型状态,抛出错误。 - 不必要的循环触发:
setData中触发dataChanged信号,进而调用handle_tableView_changed,后者又调用setTableData重置模型,形成无意义的循环操作。
解决方案
根据你的需求(修改单元格后处理数据并更新样式),提供两种针对性方案:
方案1:直接在模型中处理样式(推荐)
如果你的核心需求是根据单元格数据设置样式(如背景色),无需重置整个模型,直接在CustomTableModel的data方法中处理QBackgroundRole即可:
from PySide6.QtGui import QBrush # 需要导入QBrush class CustomTableModel(QAbstractTableModel): # ... 其他方法保持不变 ... def data(self, index, role): value = self.table_data.iat[index.row(), index.column()] if role == Qt.DisplayRole or role == Qt.EditRole: return value # 在这里添加样式逻辑 elif role == Qt.BackgroundRole: # 示例:根据单元格值设置背景色 if value == "1_1": return QBrush(Qt.lightGray) elif value.startswith("2_"): return QBrush(Qt.yellow) return None
同时删除handle_tableView_changed方法与dataChanged的绑定:
# 注释或删除这行 # self.tableView_model.dataChanged.connect(self.handle_tableView_changed)
方案2:延迟执行模型重置(必须全量更新DataFrame时使用)
如果确实需要替换整个DataFrame,通过QTimer将模型重置操作延迟到编辑器关闭后执行,避免视图与编辑器状态冲突:
from PySide6.QtCore import QTimer # 需要导入QTimer class SimpleGUI(QMainWindow): # ... 其他方法保持不变 ... def handle_tableView_changed(self, index): df = self.tableView_model.table_data.copy() ### 在这里添加你的数据处理逻辑 # 延迟执行模型更新,等编辑器完成关闭流程 QTimer.singleShot(0, lambda: self.tableView_model.setTableData(df))
代码验证
使用上述方案修改后,编辑单元格时不会再出现错误提示,同时能正常实现数据处理或样式更新的需求。
内容的提问来源于stack exchange,提问作者Vailsen Pic
相关产品推荐
相关产品推荐

