如何在QTreeView中直接关联并访问Prj对象
在QTreeView的TreeViewModel中直接关联Prj对象,避免选中时遍历匹配
核心思路
让Node类直接持有Prj对象的引用,TreeViewModel基于这些包含Prj引用的Node构建视图,选中项时直接从对应节点提取Prj实例,无需通过name遍历匹配。
具体实现步骤
1. 修改Node类,添加Prj对象存储属性
扩展原Node类,新增prj属性保存关联的Prj对象,显示文本直接从Prj对象中读取:
class Node: def __init__(self, prj=None, parent=None): self.parent = parent self.children = [] self.prj = prj # 直接存储Prj对象引用 def add_child(self, child_node): self.children.append(child_node)
2. 调整TreeViewModel的数据源构建逻辑
构建树节点时,直接将Prj对象传入Node,而非仅传入name字符串:
class Prj_Collection: def __init__(self): self.prj_dict = {} def add_prj(self, prj): self.prj_dict[prj.number] = prj def get_prj_list(self): return list(self.prj_dict.values()) # 示例:构建树结构 prj_collection = Prj_Collection() # 假设已向collection中添加若干Prj对象 prj_list = prj_collection.get_prj_list() root_node = Node() for prj in prj_list: child_node = Node(prj=prj, parent=root_node) root_node.add_child(child_node)
3. 修改TreeViewModel的data方法,从Prj对象读取显示内容
在TreeViewModel的data()方法中,直接从节点关联的Prj对象提取显示文本:
from PyQt5.QtCore import QAbstractItemModel, QModelIndex, Qt class TreeViewModel(QAbstractItemModel): def __init__(self, root_node, parent=None): super().__init__(parent) self.root_node = root_node def index(self, row, column, parent=QModelIndex()): if not self.hasIndex(row, column, parent): return QModelIndex() parent_node = parent.internalPointer() if parent.isValid() else self.root_node child_node = parent_node.children[row] return self.createIndex(row, column, child_node) def parent(self, index): if not index.isValid(): return QModelIndex() child_node = index.internalPointer() parent_node = child_node.parent if parent_node == self.root_node: return QModelIndex() return self.createIndex(parent_node.children.index(child_node), 0, parent_node) def rowCount(self, parent=QModelIndex()): parent_node = parent.internalPointer() if parent.isValid() else self.root_node return len(parent_node.children) def columnCount(self, parent=QModelIndex()): return 1 def data(self, index, role=Qt.DisplayRole): if not index.isValid(): return None node = index.internalPointer() if role == Qt.DisplayRole: return node.prj.name # 直接从Prj对象读取显示文本 elif role == Qt.ToolTipRole: return f"项目编号: {node.prj.number}" return None
4. 优化selection_changed函数,直接获取Prj对象
选中项变化时,通过选中的index直接拿到对应Node,进而获取Prj对象:
def selection_changed(selected, deselected): indexes = selected.indexes() if indexes: index = indexes[0] node = index.internalPointer() if node.prj: # 直接访问Prj对象的number属性 print(f"选中项目编号: {node.prj.number}") # 可直接操作整个Prj对象 # process_prj(node.prj) # 绑定选择信号到处理函数 tree_view.selectionModel().selectionChanged.connect(selection_changed)
优势说明
- 避免了选中时遍历所有Prj对象匹配name的性能开销,数据量越大优势越明显
- 直接关联Prj对象,后续访问其他属性无需额外查找,代码更简洁易维护
- 视图与数据模型的关联更直接,符合MVC设计模式的思想
内容的提问来源于stack exchange,提问作者user16613865
相关产品推荐
相关产品推荐

