Few days ago i searched such theme, but all i could find - how to fill tree, but not how to extract it. So i write some. Maybe someone still find this useful.
Thanks to the prev author, i used his code with some improvements.
This will load your collection (it may be list or dict or tuple with many children)
def load_tree(self, d):
self.fill_widget(self.tree, d)
def fill_widget(self, widget, value):
widget.clear()
self.fill_item(widget.invisibleRootItem(), value)
def fill_item(self, item, value):
def new_item(parent, text):
child = QTreeWidgetItem([str(text)])
if text not in ("[dict]", "[list]", "[tuple]"):
child.setFlags(child.flags() | Qt.ItemIsEditable)
parent.addChild(child)
child.setExpanded(True)
return child
if isinstance(value, dict):
new_parent = new_item(item, f"[{value.__class__.__name__}]")
for elem_k, elem_v in value.items():
sub_parent = new_item(new_parent, elem_k)
self.fill_item(sub_parent, elem_v)
elif isinstance(value, (tuple, list)):
new_parent = new_item(item, f"[{value.__class__.__name__}]")
for val in value:
self.fill_item(new_parent, val)
else:
new_item(item, f"{value}")
And extract code a little bit more.. complicated. If someone can make it more fancy - pls do.
def get_dict(self):
result = None
def unpack(to_unpack, key, source=None):
for child_index in range(to_unpack.childCount()):
child = to_unpack.child(child_index)
child_text = child.text(0)
try:
child_text = float(child_text)
except ValueError:
try:
child_text = int(child_text)
except ValueError:
pass
if source is None:
core = result
else:
core = source
if key == "[dict]":
core.update({child_text: None})
if child.childCount() > 0:
unpack(child, child_text, core)
elif key == "[list]" or key == "[tuple]":
if child_text == "[dict]":
core.append({})
elif child_text == "[list]" or child_text == "[tuple]":
core.append([])
else:
core.append(child_text)
if child.childCount() > 0:
unpack(child, child_text, core[child_index])
else:
if child_text == "[dict]":
core.update({key: {}})
elif child_text == "[list]" or child_text == "[tuple]":
core.update({key: []})
else:
core.update({key: child_text})
if child.childCount() > 0:
unpack(child, child_text, core[key])
for index in range(self.tree.topLevelItemCount()):
parent = self.tree.topLevelItem(index)
element_text = parent.text(0)
if element_text == "[dict]":
result = {}
unpack(parent, element_text)
elif element_text == "[list]" or element_text == "[tuple]":
result = []
unpack(parent, element_text)
else:
result = element_text
return result
Where self.tree - QTreeWidget object in your window.
QTreeWidget
, you really ought to use aQTreeView
backed by a model. Otherwise, you'll constantly have to repopulate the entire tree to reflect changes. – anonymous