QTreeWidget to Mirror python Dictionary
Solution 1
This is a straightforward implementation:
def fill_item(item, value):
item.setExpanded(True)
if type(value) is dict:
for key, val in sorted(value.iteritems()):
child = QTreeWidgetItem()
child.setText(0, unicode(key))
item.addChild(child)
fill_item(child, val)
elif type(value) is list:
for val in value:
child = QTreeWidgetItem()
item.addChild(child)
if type(val) is dict:
child.setText(0, '[dict]')
fill_item(child, val)
elif type(val) is list:
child.setText(0, '[list]')
fill_item(child, val)
else:
child.setText(0, unicode(val))
child.setExpanded(True)
else:
child = QTreeWidgetItem()
child.setText(0, unicode(value))
item.addChild(child)
def fill_widget(widget, value):
widget.clear()
fill_item(widget.invisibleRootItem(), value)
I added list support just in case anyone needs it.
Usage:
d = { 'key1': 'value1',
'key2': 'value2',
'key3': [1,2,3, { 1: 3, 7 : 9}],
'key4': object(),
'key5': { 'another key1' : 'another value1',
'another key2' : 'another value2'} }
widget = QTreeWidget()
fill_widget(widget, d)
widget.show()
Result:
Solution 2
Just because I recently needed this implementation for Python3 and PyQt5 here is a slightly shorter (and complete) port of the given example:
from PyQt5.QtWidgets import QApplication, QTreeWidget, QTreeWidgetItem
class ViewTree(QTreeWidget):
def __init__(self, value):
super().__init__()
def fill_item(item, value):
def new_item(parent, text, val=None):
child = QTreeWidgetItem([text])
fill_item(child, val)
parent.addChild(child)
child.setExpanded(True)
if value is None: return
elif isinstance(value, dict):
for key, val in sorted(value.items()):
new_item(item, str(key), val)
elif isinstance(value, (list, tuple)):
for val in value:
text = (str(val) if not isinstance(val, (dict, list, tuple))
else '[%s]' % type(val).__name__)
new_item(item, text, val)
else:
new_item(item, str(value))
fill_item(self.invisibleRootItem(), value)
if __name__ == '__main__':
app = QApplication([])
window = ViewTree({ 'key1': 'value1', 'key3': [1,2,3, { 1: 3, 7 : 9}]})
window.show()
app.exec_()
chase
Updated on August 05, 2022Comments
-
chase almost 2 years
Is there a way to make a
QTreeWidget
mirror the changes made to an internal data structure such as dictionary? It seems like they would have created this functionality within the api, because there are many programs which may interact withQTreeWidget
s from multiple GUI areas, but the main purpose required of theQTreeWidget
is to show a data structure at any point in time. The documentation forQtGui
items is not that simple for me to grasp as it usually refers to C documentation, and I'm not certain how it transfers to python.So essentially what I would like is the simplest manner to make a
QTreeWidget
show a nested dictionary, where the top level corresponds to the keys and the sub level corresponds to the values. Also, if the values are dictionaries, use the keys in that level and make sub levels for the values, etc.Is this easily doable? I have not been able to find anything to do simple mirroring of data structres like this yet.
-
chase over 10 yearsThis is absolutely Great! Thank you so much. This is awesome for calling each time a button is used to call some function which alters the dictionary. I ended up calling
treeWidget.clear()
beforefill_item
andtreeWidget.show()
in every function call from buttons which change the data structure. -
Pavel Strakhov over 10 yearsI added
fill_widget
function in my code for convenience. -
Reactionic almost 2 yearsThis one behaves slightly different than the given example. It adds additional child item for the value of a non-container variable which is in a container. For example
1, 2, 3
in[1,2,3, { 1: 3, 7 : 9}]
should not have a child. To fix it, the content of the loopfor val in value:
can be replaced by the code below.if isinstance(val, (str, int, float)):
text = str(val)
new_item(item, text)
else:
text = '[%s]' % type(val).__name__
new_item(item, text, val)
-
frans almost 2 yearsI've adapted your fix, thanks for the hint!