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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 16:52:42