У меня есть структура данных, которая по существу представляет собой вложенный словарь. Скажем, это выглядит так:
standard_dict = {
'section1': {
'category1': np.array([1, 2, 3, 5]),
'category2': 2
},
'section2': {
'category1': [4, 5, 6],
'category2': {'category2a': {'t': 1}}
}
}
Кроме того, у меня есть рекурсивная функция с циклом for для создания вложенного дерева из этого словаря. Теперь я пытаюсь добавить в цикл for индекс для каждого значения пары ключей. Я пробовал это с QModelindex, но я не дошел до того, что код делает то, что я хочу.
def add_object(self, v: object, prefix1: object) -> object:
if isinstance(v, dict):
for k, v2 in v.items():
prefix1.addChild(CustomNode(k))
prefix = prefix1.getlastChild()
self.add_object(v2, prefix)
elif isinstance(v, list):
for e in v:
prefix1.addChild(CustomNode(e))
Есть ли простой способ реализовать и добавить индекс к значению пары ключей?
Результат, который я хотел бы получить, - это обновить только измененные отдельные значения в графическом интерфейсе PyQt5, а не весь графический интерфейс.
Вот весь мой проект, если кто-то хочет знать.
""" import copy from typing import List, Any import sys from PyQt5 import QtCore, QtWidgets, uic import numpy as np from deepdiff import DeepDiff from lib.MainWindow import Ui_MainWindow class CustomNode(object): def __init__(self, data): self._data = data if type(data) == tuple: self._data = list(data) if type(data) is str or not hasattr(data, '__getitem__'): self._data = [data] self._columncount = len(self._data) self._children = [] self._parent = None self._row = 0 def getlastChild(self): return self._children[-1] def data(self, column): if column >= 0 and column < len(self._data): return self._data[column] def columnCount(self): return self._columncount def childCount(self): return len(self._children) def child(self, row): if row >= 0 and row < self.childCount(): return self._children[row] def parent(self): return self._parent def row(self): return self._row def addChild(self, child): child._parent = self child._row = len(self._children) self._children.append(child) self._columncount = max(child.columnCount(), self._columncount) class CustomModel(QtCore.QAbstractItemModel): def __init__(self, nodes): QtCore.QAbstractItemModel.__init__(self) self._root = CustomNode(None) for node in nodes: self._root.addChild(node) def rowCount(self, index: object) -> object: if index.isValid(): return index.internalPointer().childCount() return self._root.childCount() def addChild(self, node, _parent): if not _parent or not _parent.isValid(): parent = self._root else: parent = _parent.internalPointer() parent.addChild(node) def index(self, row, column, _parent=None): if not _parent or not _parent.isValid(): parent = self._root else: parent = _parent.internalPointer() if not QtCore.QAbstractItemModel.hasIndex(self, row, column, _parent): return QtCore.QModelIndex() child = parent.child(row) if child: return QtCore.QAbstractItemModel.createIndex(self, row, column, child) else: return QtCore.QModelIndex() def parent(self, index): if index.isValid(): p = index.internalPointer().parent() if p: return QtCore.QAbstractItemModel.createIndex(self, p.row(), 0, p) return QtCore.QModelIndex() def columnCount(self, index): if index.isValid(): return index.internalPointer().columnCount() return self._root.columnCount() def data(self, index, role): if not index.isValid(): return None node = index.internalPointer() if role == QtCore.Qt.DisplayRole: return node.data(index.column()) return None class MyTree(): def __init__(self, ref_dict, treeView): self.items = [] self.ref_dict = ref_dict self.items = [] self.index_dict = ref_dict '''Erzeugt eine List aus den Hauptitems''' for key in self.ref_dict: self.items += [CustomNode(key)] self.add_object(self.ref_dict[key], prefix1=self.items[-1]) '''Aufruf der View um die Anzeige darzustellen''' # self.tw = QtWidgets.QTreeView() self.tw = treeView self.tw.setModel(CustomModel(self.items)) #referenz auf das Modell, gibt das Modell zurück print(self.tw.model()) '''Funktion um das Dictionary zu iterieren und in einer Treeview darzustellen''' def add_object(self, v: object, prefix1: object) -> object: if isinstance(v, dict): for k, v2 in v.items(): prefix1.addChild(CustomNode(k)) prefix = prefix1.getlastChild() self.add_object(v2, prefix) elif isinstance(v, list): for e in v: prefix1.addChild(CustomNode(e)) elif isinstance(v, type(np.array([]))): [prefix1.addChild(CustomNode(int(i))) for i in v] else: prefix1.addChild(CustomNode(v)) class Compare(): def __init__(self, standard_dict): self.__standard_dict = copy.deepcopy(standard_dict) @property def standard_dict(self): return self.__standard_dict @standard_dict.setter def standard_dict(self, standard_dict): self.__standard_dict = standard_dict # Signal auslösen mit kompletten Update vom Model '''Funktion um mit DeepDiff die beiden Dictionaries zu vergleichen''' def compare(self, new_dict): return DeepDiff(self.__standard_dict, new_dict) class MainWindow(QtWidgets.QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) mytree = MyTree(standard_dict, self.ui.treeView) mytree_2 = MyTree(standard_dict, self.ui.treeView_2) self.ui.pushButton.clicked.connect(self.compare_dict) self.comp = Compare(standard_dict=standard_dict) def compare_dict(self): standard_dict['section1']['category2'] += 1 diff = self.comp.compare(standard_dict) self.ui.plainTextEdit.insertPlainText(str(standard_dict)) self.ui.plainTextEdit.insertPlainText(str(diff)) #mytree_3 = MyTree(standard_dict, self.ui.treeView_2) #nur die Stelle des geänderten Indexes updaten und keine neue View erstellen if __name__ == "__main__": standard_dict = { 'section1': { 'category1': np.array([1, 2, 3, 5]), 'category2': 2 }, 'section2': { 'category1': [4, 5, 6], 'category2': {'category2a': {'t': 1}} } } app = QtWidgets.QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
Заранее большое спасибо
dict
сenumerate
и распаковать индекс, ключ и значение вместе с итерацией может быть полезно. - person hemmelig   schedule 24.06.2020