Important: Please read the Qt Code of Conduct -

QTreeView questions

  • Hello!

    I've got a couple of questions about QTreeView.

    First things first: I'm using PySide6.

    Currently I've got a QTreeView which loads a series of nested items. The first time it loads them, it works almost flawlessly: the thing that's not working is that it shows an empty row at the bottom which, if clicked, crashes the UI without any traceback.

    If I don't touch the last row and try to update the model (by removing all the rows and filling it again with new rows), the application eats all the memory in a couple of seconds (something like... 32GB of RAM) and I'm forced to kill it.

    I'm doing something wrong for sure.

    This is the code I've written for it:

        def load_functions_from_project(self):
            logger = logging.getLogger(__name__)
            model = self.functionsTreeView.model()
            if not model:
                model = QStandardItemModel()
            self.functionsTreeView.setUpdatesEnabled(False)  # Attempt to optimize
            if model.hasChildren():
                model.removeRows(0, model.rowCount())  # here it eats all the memory and freezes
            if not self.project:
            functions = self.project.functions  # just a dataclass
            functions.sort(key=lambda fn: f'{fn.module}{}')
            rootNode = model.invisibleRootItem()
            items: Dict[str, TreeItem] = {}
            for fn in functions:
                module_path = fn.module.split('.')  # a.b.c.d
                current_path = ''
                for path in module_path:
                    previous_path = current_path
                    if not previous_path:
                        current_path = path
                        current_path = '.'.join([current_path, path])
                    if current_path not in items:
                        node = TreeItem(text=path)  # It's a subclass of QStandardItem which sets enabled, text, drag enabled
                        items[current_path] = node
                        if not previous_path:
                node = TreeItem(, function=fn)

    May you please help me?

    Thank you very much :)

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    @jim87 said in QTreeView questions:

    model.removeRows(0, model.rowCount()) # here it eats all the memory and freezes

    Aren't you removing one row too many ?

    [edit: wrong function signature in mind SGaist]

  • @SGaist said in QTreeView questions:

    Aren't you removing one row too many ?

    Why do you say this? [Unless there is something about using a model for a QTreeView requiring one to preserve one item, but I'm not aware of that.]

    [removeRows() takes a count of rows to remove, not an index-of-last-row if that's what you're thinking?]

  • @SGaist I tried replacing the whole model with, say, self.functionsTreeView.setModel(None) - same result of eating memory and freezing

  • @jim87
    It's probably not relevant, but you leave treeview updates disabled. I assume your second


    near the end is supposed to pass True. Correct that and/or comment out these "optimizations" while diagnosing the problem.

  • @JonB thanks to pointing that out. Unfortunately this did nothing about the problem.

    I think we should concentrate on the empty item which shouldn't be there:


    According to the code, there should be at least a Function with an empty 'module' attribute, but there isn't:


  • Ok, I've made a PoC for this issue, where both the "extra" tree element appears and when you try to load twice it will eat all the memory, freezing .

    I'm running Python 3.10.1 with PySide6 under Linux Fedora 35.

    I can't attach the zip file here, though you can download it from the following link:

    Thanks :)

    EDIT: I finally caught the error! I was creating the model's root item and I was appending all the items in it, though I was also appending the root item to the model itself (see line 184 of the last example). It was as easy as that.

    Thanks for the support though :)