Search code examples
pythonpyqtpyqt4qtreeview

Creating QTreeView hierarchy from a given list


Given a list of strings, I am trying to populate the items in a tree view. Here is my code:

class MyModel(QtGui.QStandardItemModel):
    def __init__(self, parent=None):
        super(MyModel, self).__init__(parent)
        self.get_contents()

    def get_contents(self):
        self.clear()
        contents = [
            '|Base|character|Mike|body',
            '|Base|character|John',
            '|Base|camera'
        ]

        for content in contents:
            count = content.count('|')
            for index in range(count):
                index = index + 2
                split_path = content.split('|')[0:index]
                self.add_item(split_path)

    def add_item(self,name):
        item1 = QtGui.QStandardItem(name)
        self.appendRow([item1])

However, the hierarchy that I have got in my Tree View are not collapsible (those with the small arrow icons by the side) and each row is appended with values and editable (if double click), in which I do not want.

An example of the output from my code:

|Base
|Base|character
|Base|character|Mike
|Base|character|Mike|body
|Base
|Base|character
|Base|character|John
|Base
|Base|camera

where there are a few repeatable rows...

And this is what I am expecting:

|-- Base
|--|-- character
|--|--|-- Mike
|--|--|--|-- body
|--|-- character
|--|--|-- John
|--|-- camera

Any insights?


Solution

  • You have to add the children if this is not part of the children, also you must remove the first element of the result of the split() since it is an empty element:

    from PyQt4 import QtCore, QtGui
    
    
    class MyModel(QtGui.QStandardItemModel):
        def __init__(self, parent=None):
            super(MyModel, self).__init__(parent)
            self.get_contents()
    
        def get_contents(self):
            self.clear()
            contents = [
                '|Base|character|Mike|body',
                '|Base|character|John',
                '|Base|camera'
            ]
    
            for content in contents:
                parent = self.invisibleRootItem()
                for word in content.split("|")[1:]:
                    for i in range(parent.rowCount()):
                        item = parent.child(i) 
                        if item.text() == word:
                            it = item
                            break
                    else:
                        it = QtGui.QStandardItem(word)
                        parent.setChild(parent.rowCount(), it)
                    parent = it
    
    
    if __name__ == '__main__':
        import sys
    
        app = QtGui.QApplication(sys.argv)
    
        w = QtGui.QTreeView()
        model = MyModel(w)
        w.setModel(model)
        w.show()
        w.expandAll()
        sys.exit(app.exec_())
    

    enter image description here