PySide:QTreeView 到嵌套字典
PySide: QTreeView to nested dictionary
我需要帮助从 QTreeView 结构构建分层嵌套 dict 以获得如下内容:
{"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 代表一个目录结构(我实际上是从上面的字典中提取它,只是想在修改树后重新创建字典)
我已经有这样的东西了:
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
这里的问题是......我需要在 _structure 字典中找到 _parent 键,据我所知,它总是在字典的最低级别......我真的需要搜索whole _structure dict 每次都想向给定的 _parent 添加一个新的 subdict 或者是否有更好的解决方案来解决我的问题?
要将字典转换为模型,则必须递归迭代字典,并根据数据类型将其插入模型。反之亦然。
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_())
我需要帮助从 QTreeView 结构构建分层嵌套 dict 以获得如下内容:
{"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 代表一个目录结构(我实际上是从上面的字典中提取它,只是想在修改树后重新创建字典)
我已经有这样的东西了:
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
这里的问题是......我需要在 _structure 字典中找到 _parent 键,据我所知,它总是在字典的最低级别......我真的需要搜索whole _structure dict 每次都想向给定的 _parent 添加一个新的 subdict 或者是否有更好的解决方案来解决我的问题?
要将字典转换为模型,则必须递归迭代字典,并根据数据类型将其插入模型。反之亦然。
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_())