如何基于PyQt5与SQLite实现带父子层级的QTreeWidget
实现方案
核心逻辑
- 查询数据库时要获取
ID、PARENTID、NAME三个字段,仅拿名称无法做层级关联 - 用字典存ID和对应节点对象的映射,能快速定位父节点,避免遍历树的开销
- 先创建所有节点存到字典,再统一根据PARENTID绑定父子关系:如果PARENTID存在于字典中,就作为该父节点的子项;如果PARENTID为空/0,就挂载到你预设的顶层根节点下
修改后的printtree代码
def printtree(self): rn = readsql_Names() self.treeWidget.setColumnCount(1) # 预设的顶层根节点 root_item = QtWidgets.QTreeWidgetItem([rn]) self.treeWidget.addTopLevelItem(root_item) def displaytree(): conn = connect_DB() cursor = conn.cursor() # 一次性查出所有字段 cursor.execute("SELECT ID, PARENTID, NAME FROM Test") all_records = cursor.fetchall() # 存储ID和对应节点的映射 id_item_map = {} # 第一步:创建所有节点并存入字典 for record in all_records: item_id, parent_id, name = record item = QtWidgets.QTreeWidgetItem([str(name)]) # 把ID存在节点的data里,后续新增同步、节点操作时可直接取用 item.setData(0, QtCore.Qt.UserRole, item_id) id_item_map[item_id] = item # 第二步:绑定父子关系 for record in all_records: item_id, parent_id, name = record current_item = id_item_map[item_id] # 这里判断规则可根据你的实际需求调整,比如PARENTID为0/NULL时挂到顶层根节点 if parent_id is None or parent_id == 0: root_item.addChild(current_item) else: # 父ID存在映射,就挂到父节点下 if parent_id in id_item_map: parent_item = id_item_map[parent_id] parent_item.addChild(current_item) cursor.close() conn.close() displaytree() # 可选:默认展开所有节点,方便查看效果 self.treeWidget.expandAll()
新增数据实时同步补充
如果需要新增数据时不用刷新整棵树,只需要在插入数据库成功后,拿到新记录的ID、PARENTID、NAME创建新节点,通过PARENTID从映射字典里找到对应父节点挂载即可,映射字典可以提为类属性方便全局调用。
内容的提问来源于stack exchange,提问作者Saizzou
相关产品推荐
相关产品推荐

