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
QtWS25 Last Chance

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