Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. QTreeView questions

QTreeView questions

Scheduled Pinned Locked Moved Solved Qt for Python
pysidepythonqt for python
7 Posts 3 Posters 1.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jim87
    wrote on last edited by
    #1

    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.setModel(model)
    
            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:
                return
    
            functions = self.project.functions  # just a dataclass
            functions.sort(key=lambda fn: f'{fn.module}{fn.name}')
    
            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
                    else:
                        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:
                            rootNode.appendRow(node)
                        else:
                            items[previous_path].appendRow(node)
                node = TreeItem(text=fn.name, function=fn)
                items[fn.module].appendRow(node)
    
            model.appendRow(rootNode)
            self.functionsTreeView.setUpdatesEnabled(False)
    
            self.functionsTreeView.collapseAll()
    

    May you please help me?

    Thank you very much :)

    SGaistS 1 Reply Last reply
    0
    • J jim87

      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.setModel(model)
      
              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:
                  return
      
              functions = self.project.functions  # just a dataclass
              functions.sort(key=lambda fn: f'{fn.module}{fn.name}')
      
              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
                      else:
                          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:
                              rootNode.appendRow(node)
                          else:
                              items[previous_path].appendRow(node)
                  node = TreeItem(text=fn.name, function=fn)
                  items[fn.module].appendRow(node)
      
              model.appendRow(rootNode)
              self.functionsTreeView.setUpdatesEnabled(False)
      
              self.functionsTreeView.collapseAll()
      

      May you please help me?

      Thank you very much :)

      SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by SGaist
      #2

      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]

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      JonBJ J 2 Replies Last reply
      0
      • SGaistS SGaist

        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]

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #3

        @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?]

        1 Reply Last reply
        0
        • SGaistS SGaist

          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]

          J Offline
          J Offline
          jim87
          wrote on last edited by
          #4

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

          JonBJ 1 Reply Last reply
          0
          • J jim87

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

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #5

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

            self.functionsTreeView.setUpdatesEnabled(False)
            

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

            J 1 Reply Last reply
            0
            • JonBJ JonB

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

              self.functionsTreeView.setUpdatesEnabled(False)
              

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

              J Offline
              J Offline
              jim87
              wrote on last edited by
              #6

              @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:

              d721a2ca-ab01-4ecc-bc58-eda9159b89ee-immagine.png

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

              5f7283cb-8aad-407c-83ee-c318553c634f-immagine.png

              1 Reply Last reply
              0
              • J Offline
                J Offline
                jim87
                wrote on last edited by jim87
                #7

                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 6.2.2.1 under Linux Fedora 35.

                I can't attach the zip file here, though you can download it from the following link: https://drive.google.com/file/d/1vBZDIAZGhnS_Gi-rFalpxZKgB5zqLh7a/view?usp=sharing

                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 :)

                1 Reply Last reply
                1

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved