PySide: QTreeView для вложенного словаря - PullRequest
0 голосов
/ 12 декабря 2018

Мне нужна помощь для построения иерархического вложенного dict из структуры QTreeView, чтобы получить что-то вроде этого:

 {"A": {"B": {"H": {}, "I": {"M": {}, "N": {}}}, "D": {}, "E": {}, "F": {}, "G": {"L": {}}, "C": {"J": {}, "K": {}}}}

{
    "A": {
        "B": {
            "H": {}, 
            "I": {
                "M": {}, 
                "N": {}
             }
        }, 
        "D": {}, 
        "E": {}, 
        "F": {}, 
        "G": {
            "L": {}
        }, 
        "C": {
            "J": {}, 
            "K": {}
        }
    }
}

Я не использую столбцы в этом случае, и QTreeView представляет структуру каталогов (я фактически извлек)это от dict как тот выше и просто хочу воссоздать dict после модификации Дерева)

У меня уже есть кое-что как это:

def to_dict(self, _structure={}, _parent=''):
    sublist[self.name()] = self._children

    for child in self._children:
        _structure[self.name()] = sublist
        child.to_dict(_structure, self.name())

Очевидно, что self._children - списоктак что это не будет работать

РЕДАКТИРОВАТЬ: Я думаю, что мне может понадобиться что-то вроде этого:

def to_dict(self, _structure={}, _parent=''):

    sublist = {self.name(): {}}

    for child in self._children:
        if _parent == '':
            _structure = sublist
        else:
            _structure[_parent].update(sublist)
        child.to_dict(_structure, self.name())

    return _structure

Проблема здесь ... мне нужно найти ключ _parent в словаре _structure и какНасколько я понимаю, это всегда будет на самом низком уровне dict ... действительно ли мне нужно искать всю _структурную реплику каждый раз, когда я хочу добавить новый subdict к данному _parent или есть лучшее решение моей проблемы?

1 Ответ

0 голосов
/ 12 декабря 2018

Чтобы преобразовать словарь в модель, необходимо выполнить рекурсивную итерацию по словарю и в соответствии с типом данных вставить его в модель.В противоположном случае это то же самое.

from PySide import QtCore, QtGui

def fill_model_from_json(parent, d):
    if isinstance(d, dict):
        for k, v in d.items():
            child = QtGui.QStandardItem(str(k)) 
            parent.appendRow(child)
            fill_model_from_json(child, v)
    elif isinstance(d, list):
        for v in d:
            fill_model_from_json(parent, v)
    else:
        parent.appendRow(QtGui.QStandardItem(str(d)))

def fill_dict_from_model(parent_index, d):
    v = {}
    for i in range(model.rowCount(parent_index)):
        ix = model.index(i, 0, parent_index)
        fill_dict_from_model(ix, v)
    d[parent_index.data()] = v

def model_to_dict(model):
    d = dict()
    for i in range(model.rowCount()):
        ix = model.index(i, 0)
        fill_dict_from_model(ix, d)    
    return d

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    tree = QtGui.QTreeView()
    model = QtGui.QStandardItemModel()
    data =  {"A": {"B": {"H": {}, "I": {"M": {}, "N": {}}}, "D": {}, "E": {}, "F": {}, "G": {"L": {}}, "C": {"J": {}, "K": {}}}}
    fill_model_from_json(model.invisibleRootItem(), data)
    tree.setModel(model)
    tree.expandAll()
    tree.resize(360, 480)
    tree.show()
    d = model_to_dict(model)
    assert(d == data)
    print(d)
    sys.exit(app.exec_())

enter image description here

...