Search code examples
pythonpyqt5qtreeviewqstandarditem

After adding row to a parent node, modify parent to show number of children below


I'm looping through my data, using addrow to either the root node or to parent off it (etc.). Now for the parent how to modify the 2nd cell in the parent to show the current number of children, then update that cell, as I add more children?


Solution

  • One possible solution is to use the rowsInserted and rowsRemoved signals from the model to calculate the number of children. On the other hand, a simpler solution is to use a delegate:

    import random
    
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class Delegate(QtWidgets.QStyledItemDelegate):
        def initStyleOption(self, option, index):
            super().initStyleOption(option, index)
            if not index.parent().isValid() and index.column() == 1:
                model = index.model()
                sibling = index.sibling(index.row(), 0)
                option.text = f"{model.rowCount(sibling)} childs"
    
    
    def main():
        app = QtWidgets.QApplication([])
    
        model = QtGui.QStandardItemModel(0, 2)
    
        for i in range(4):
            item = QtGui.QStandardItem(f"parent-{i}")
            model.appendRow(item)
    
        view = QtWidgets.QTreeView()
        delegate = Delegate(view)
        view.setItemDelegate(delegate)
        view.setModel(model)
        view.resize(640, 480)
        view.show()
    
        def handle_timeout():
            for i in range(4):
                root_item = model.item(i)
                for j in range(random.randint(3, 5)):
                    item = QtGui.QStandardItem(f"child-{i}-{j}")
                    root_item.appendRow(item)
            view.expandAll()
    
        QtCore.QTimer.singleShot(2 * 1000, handle_timeout)
    
        app.exec_()
    
    
    if __name__ == "__main__":
        main()