QTreeWidget to Mirror python Dictionary

Is there a way to make the QTreeWidget mirror make changes to an internal data structure, such as a dictionary? It seems like they would create this functionality in the api, because there are many programs that can interact with QTreeWidget from several areas of the GUI, but the main purpose needed for QTreeWidget is to show the data structure at any point in time. The documentation for QtGui elements is not QtGui for me to understand, since it usually refers to the C documentation, and I'm not sure how it is passed to python.

So, in essence, I would like the easiest way to make QTreeWidget show a nested dictionary where the top level corresponds to the keys and the auxiliary level corresponds to the values. Also, if the values ​​are dictionaries, use the keys at that level and create sub-selections for the values, etc.

Is it easy to do? I have not yet been able to find anything to make a simple mirror image of data structures like this.

+7
python qt pyqt qtreewidget
source share
3 answers

This is a simple 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 someone needs it.

Using:

 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:

screenshot

+16
source share

Just because I recently needed this implementation for Python3 and PyQt5, here is a slightly shorter (and full) port of this 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_() 
+1
source share

I found that recursion makes it rather slow when creating a tree structure of a huge directory structure. This method may help.

  def update_right_dock(self, file_list): obj_list = [] maps = [] level = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] #Stores Maximum and Current Levels For The TreeWidget level_name = ["", "", "", "", "", "", "", "", "", "", "", "", "", ""] #Stores Previous File Path To Compare before adding file or folder to tree tree.clear() prev = "" tot_len = 2 p = 0 for file in file_list: if(os.path.isdir(file)): is_file = 0 else: is_file = 1 tmp_map = [] file = file[1:] abs_path = file.split('/') abs_path_len = len(abs_path) filename = abs_path[-1] if(prev == file[:tot_len - 1]): #print("LOOOOOOOOOOOOP ------ 1") while (i < abs_path_len - 1): level[level_counter + 1] = QTreeWidgetItem(level[level_counter], [abs_path[i]]) tmp_map.append(level[level_counter + 1]) tmp_map.append(level_counter + 1) tmp_map.append(1) obj_list.append(tmp_map) tmp_map = [] level[level_counter + 1].setCheckState(0, Qt.Checked) tree.expandItem(level[level_counter + 1]) level_counter = level_counter + 1 level_name[i] = abs_path[i] i = i + 1 level[level_counter + 1] = QTreeWidgetItem(level[level_counter], [abs_path[i]]) tmp_map.append(level[level_counter + 1]) tmp_map.append(level_counter + 1) tmp_map.append(0) obj_list.append(tmp_map) tmp_map = [] level[level_counter + 1].setCheckState(0, Qt.Checked) tree.expandItem(level[level_counter + 1]) file_len = len(filename) tot_len = len(file) - file_len prev = file[:tot_len - 1] continue len2 = len(level_name) k = 0 while k < abs_path_len and k < len2: if (level_name[k] == abs_path[k]): k = k + 1 continue break level_counter = k + 1 i = level_counter - 1 while k < abs_path_len: level_name[k] = abs_path[k] k = k + 1 if level_counter > 1: #print("LOOOOOOOOOOOOP ------ 2") if(i == abs_path_len - 1): level_counter = level_counter - 1 while i < abs_path_len - 1: level[level_counter] = QTreeWidgetItem(level[level_counter - 1], [abs_path[i]]) tmp_map.append(level[level_counter]) tmp_map.append(level_counter) tmp_map.append(1) obj_list.append(tmp_map) tmp_map = [] level[level_counter].setCheckState(0, Qt.Checked) tree.expandItem(level[level_counter]) level_counter = level_counter + 1 level_name[i] = abs_path[i] i = i + 1 if i == abs_path_len - 1: level_counter = level_counter - 1 level[level_counter + 1] = QTreeWidgetItem(level[level_counter], [abs_path[i]]) tmp_map.append(level[level_counter + 1]) tmp_map.append(level_counter + 1) tmp_map.append(0) obj_list.append(tmp_map) tmp_map = [] level[level_counter + 1].setCheckState(0, Qt.Checked) tree.expandItem(level[level_counter + 1]) file_len = len(filename) tot_len = len(file) - file_len prev = file[:tot_len - 1] continue if(abs_path_len == 1): level[level_counter + 1] = QTreeWidgetItem(tree, [abs_path[i]]) tmp_map.append(level[level_counter + 1]) tmp_map.append(level_counter + 1) tmp_map.append(0) obj_list.append(tmp_map) tmp_map = [] level[level_counter + 1].setCheckState(0, Qt.Checked) tree.expandItem(level[level_counter + 1]) continue i = 1 #print("LOOOOOOOOOOOOP ------ 3") level[level_counter] = QTreeWidgetItem(tree, [abs_path[0]]) tmp_map.append(level[level_counter]) tmp_map.append(level_counter) tmp_map.append(1) obj_list.append(tmp_map) tmp_map = [] level[level_counter].setCheckState(0, Qt.Checked) tree.expandItem(level[level_counter]) level_name[level_counter - 1] = abs_path[0] while i < abs_path_len - 1: level[level_counter + 1] = QTreeWidgetItem(level[level_counter], [abs_path[i]]) tmp_map.append(level[level_counter + 1]) tmp_map.append(level_counter + 1) tmp_map.append(1) obj_list.append(tmp_map) tmp_map = [] level[level_counter + 1].setCheckState(0, Qt.Checked) tree.expandItem(level[level_counter + 1]) level_counter = level_counter + 1 level_name[i] = abs_path[i] if i == abs_path_len - 1: level_counter = level_counter - 1 i = i + 1 level[level_counter + 1] = QTreeWidgetItem(level[level_counter], [abs_path[i]]) tmp_map.append(level[level_counter + 1]) tmp_map.append(level_counter + 1) tmp_map.append(0) obj_list.append(tmp_map) tmp_map = [] level[level_counter + 1].setCheckState(0, Qt.Checked) tree.expandItem(level[level_counter + 1]) level_name[i] = abs_path[i] file_len = len(filename) tot_len = len(file) - file_len prev = file[:tot_len - 1] p = p + 1 
0
source share

All Articles