QTreeView如何为指定索引单元格设置QStyledItemDelegate
实现方案
QTreeView 没有提供直接为单个单元格绑定独立委托的原生接口,最简便可行的方案是实现一个路由委托,按索引位置将编辑、渲染逻辑转发给对应子委托,完全满足你给指定单元格单独配置委托的需求。
核心实现逻辑
- 新建一个继承自
QStyledItemDelegate的总路由委托,内部维护单元格索引到对应委托实例的映射表 - 重写委托的所有核心方法,每次触发时先判断当前索引是否在映射表中:如果存在匹配的子委托,就把方法调用转发给子委托处理;如果不存在,就执行
QStyledItemDelegate的默认逻辑 - 将这个总路由委托设置给视图的对应列(你的场景里是第1列)即可
如果你的场景里单元格规则固定、数量不多,也可以直接在单个委托的createEditor等方法里,通过index.row()和index.column()判断位置,直接返回对应编辑器,不需要拆分多个委托类,代码更简洁。
可运行修改示例
import sys from PySide2.QtWidgets import * from PySide2.QtGui import * from PySide2.QtCore import * class Delegate_1(QStyledItemDelegate): def createEditor(self, parent, option, index): combo = QComboBox(parent) combo.addItem('BINARY') combo.addItem('ASCII') return combo def setModelData(self, editor, model, index): model.setData(index, editor.currentText()) class Delegate_2(QStyledItemDelegate): def createEditor(self, parent, option, index): combo = QComboBox(parent) combo.addItem('True') combo.addItem('False') return combo def setModelData(self, editor, model, index): model.setData(index, editor.currentText()) class CellDelegateDispatcher(QStyledItemDelegate): def __init__(self, parent=None): super().__init__(parent) # 存储 索引:委托实例 的映射 self._delegate_map = {} def set_delegate_for_index(self, index: QModelIndex, delegate: QStyledItemDelegate): """为指定模型索引绑定专属委托""" self._delegate_map[index] = delegate def _get_target_delegate(self, index): """获取当前索引对应的委托,没有匹配则返回自身走默认逻辑""" return self._delegate_map.get(index, self) # 以下重写所有核心委托方法,做逻辑转发 def createEditor(self, parent, option, index): return self._get_target_delegate(index).createEditor(parent, option, index) def setEditorData(self, editor, index): self._get_target_delegate(index).setEditorData(editor, index) def setModelData(self, editor, model, index): self._get_target_delegate(index).setModelData(editor, model, index) def updateEditorGeometry(self, editor, option, index): self._get_target_delegate(index).updateEditorGeometry(editor, option, index) def paint(self, painter, option, index): self._get_target_delegate(index).paint(painter, option, index) def sizeHint(self, option, index): return self._get_target_delegate(index).sizeHint(option, index) if __name__ == '__main__': app = QApplication(sys.argv) model = QStandardItemModel(2, 2) it = QStandardItem('File_mode') model.setItem(0, 0, it) it = QStandardItem('ASCII') model.setItem(0, 1, it) it = QStandardItem('Opened') model.setItem(1, 0, it) it = QStandardItem('True') model.setItem(1, 1, it) t = QTreeView() t.setModel(model) # 初始化路由委托 dispatcher_delegate = CellDelegateDispatcher(t) # 为指定单元格绑定对应委托 dispatcher_delegate.set_delegate_for_index(model.index(0, 1), Delegate_1()) dispatcher_delegate.set_delegate_for_index(model.index(1, 1), Delegate_2()) # 把路由委托设置给第1列 t.setItemDelegateForColumn(1, dispatcher_delegate) t.show() sys.exit(app.exec_())
注意:创建QComboBox编辑器时必须传入parent参数,否则编辑器弹出时可能出现焦点异常、窗口闪退的问题。
内容的提问来源于stack exchange,提问作者Juan
相关产品推荐
相关产品推荐

