# coding=utf-8 from typing import Dict, Union, List from PyQt5.QtGui import QStandardItem, QStandardItemModel from PyQt5.QtCore import Qt class TreeViewModel(QStandardItemModel): def __init__(self, parent = None): super().__init__(parent) def _create_item(self, parent_model: Union[QStandardItem, QStandardItemModel], name: str, data: Dict) -> QStandardItem: item = QStandardItem(name) for user_role, row_data in data.items(): item.setData(row_data, user_role) parent_model.appendRow(item) return item def get_item(self, path: List[str], item_name: str): parents = [None] for i, name in enumerate(path + [item_name]): parent_model = self if i == 0 else parents[-1] items = self.findItems(name, Qt.MatchExactly | Qt.MatchRecursive) target_item = None if not items: # create new item if it does not exist target_item = self._create_item(parent_model, name, {Qt.UserRole: "", Qt.UserRole+1: ""}) else: for item in items: # check found items with corresponding parent if item.parent() == parents[-1]: target_item = item if target_item is None: target_item = self._create_item(parent_model, name, {Qt.UserRole: "", Qt.UserRole + 1: ""}) parents.append(target_item) return parents[-1] def clear_sub_tree(self, path: List[str], item_name: str) -> None: index = self.get_item(path, item_name).index() self.removeRows(0, self.rowCount(index), index) def remove_sub_tree(self, path: List[str], item_name: str) -> None: index = self.get_item(path, item_name).index() parent_index = index.parent() self.removeRows(index.row(), 1, parent_index) def roleNames(self) -> Dict: return { Qt.DisplayRole: "name_col".encode(), Qt.UserRole: "value_col".encode(), Qt.UserRole + 1: "type_col".encode() } def set_item_data(self, path, name, value, value_type) -> None: item = self.get_item(path, name) item.setData(value, Qt.UserRole) item.setData(value_type, Qt.UserRole + 1)