Python Forum

Full Version: How to populate a treeview on a GUI with a dictionary
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have a treeview on my GUI called 'treeView'.
I have a dictionary which contains the following:

{"Pipe 1": {'1.Name': 'ABC', '2.Outside diameter': '10', '3.Wall thickness': '5', '4.Density': '7850', '5.Liner layers': {1: {'1.Liner name': 'SAD', '2.Liner thickness': '5', '3.Liner density': '900'}}, '6.Coating layers': {1: {'1.Coating name': 'TWR', '2.Coating thickness': '50', '3.Coating density': '3000', '4.Coating cutback': '0.7', '5.Coating absorption': '4'}}}}
How do I get the dictionary into the respective treeview such that it shows:

Pipe 1
1.Name
2.Outer diameter
3.Wall thickness
4.Density
5.Liner layers
1. Liner name
2. Liner thickness
3. Liner density
6.Coating layers
1.Coating name
2.Coating thickness
3.Coating density
4.Coating cutback
5.Coating absorption

I have found the below code but, it shows a new window instead of showing it into the treeview on the GUI and I have no experience in adjusting it to suit my needs yet.

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({"Pipe 1": {'1.Name': 'ABC', '2.Outside diameter': '10', '3.Wall thickness': '5', '4.Density': '7850', '5.Liner layers': {1: {'1.Liner name': 'SAD', '2.Liner thickness': '5', '3.Liner density': '900'}}, '6.Coating layers': {1: {'1.Coating name': 'TWR', '2.Coating thickness': '50', '3.Coating density': '3000', '4.Coating cutback': '0.7', '5.Coating absorption': '4'}}}})
    window.show()
    app.exec_()
Additionally it shows 1 on the top, instead of starting at 'Pipe 1'.
Here is a tree view that I wrote that displays Category with their Sub-Groups a version of this should work for you and it works within the tree view itself
    def SetContent(self, tmpCatGrpList):
        self.model.setRowCount(0)
        TreeRoot = self.model.invisibleRootItem()
        SeenCat = {}
        QuedData = deque(tmpCatGrpList)

        while QuedData:
            Itm = QuedData.popleft()
            CurNode = TreeRoot
            CatNam = Itm['CatgryName']
            GrpNam = Itm['GroupName']

            if CatNam in SeenCat:
                CurNode = SeenCat[CatNam]
                CurNode.appendRow([QStandardItem(GrpNam)])
            else:
                CurNode.appendRow([QStandardItem(CatNam)])
                if len(GrpNam) > 0:
                    CurNode = CurNode.child(CurNode.rowCount() - 1)
                    CurNode.appendRow([QStandardItem(GrpNam)])

                SeenCat[CatNam] = CurNode
        
        # Initialize Selection to First Row 'All'
        self.setCurrentIndex(self.model.index(0, 0))
Note you most likely will not need the QuedData = deque(tmpCatGrpList) line as yours seems to be a straight pass through but who knows