Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTreeView memory consumption increasing
Qt 6.11 is out! See what's new in the release blog

QTreeView memory consumption increasing

Scheduled Pinned Locked Moved Unsolved General and Desktop
16 Posts 5 Posters 3.3k Views 1 Watching
  • 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.
  • JoeCFDJ JoeCFD

    @jinming Jon is right. Better to display on demand. It is unnecessary to add all of them all in once.

    #include <QApplication>
    #include <QMainWindow>
    #include <QTreeWidget>
    #include <QTreeWidgetItem>
    #include <QScrollBar>
    #include <QVBoxLayout>
    
    class MyWindow : public QMainWindow {
       Q_OBJECT
    
    public:
       MyWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
           treeWidget = new QTreeWidget(this);
           treeWidget->setColumnCount(1);
           treeWidget->setHeaderLabels({"Items"});
    
           setCentralWidget(treeWidget);
    
           // Connect the itemEntered signal to the slot
           connect(treeWidget, &QTreeWidget::itemEntered, this, &MyWindow::onItemEntered);
    
           // Populate the initial items
           populateTree();
    
           // Connect the scroll bar value changed signal to the slot
           connect(treeWidget->verticalScrollBar(), &QScrollBar::valueChanged, this, &MyWindow::onVerticalScroll);
       }
    
       void populateTree() {
           // Add some top-level items
           for (int i = 0; i < 50; ++i) {
               QTreeWidgetItem *topItem = new QTreeWidgetItem(treeWidget, QStringList() << "Top Item " + QString::number(i));
               // Add a dummy child item to make the parent item expandable
               new QTreeWidgetItem(topItem, QStringList() << "Loading...");
           }
       }
    
    public slots:
       void onItemEntered(QTreeWidgetItem *item, int column) {
           // Check if the item already has child items (the dummy item for loading)
           if (item->child(0) && item->child(0)->text(0) == "Loading...") {
               // Remove the dummy item
               delete item->takeChild(0);
               // Load and add the actual child items
               for (int i = 0; i < 3; ++i) {
                   new QTreeWidgetItem(item, QStringList() << "Child Item " + QString::number(i));
                   // Add more child items or load data as needed
               }
           }
       }
    
       void onVerticalScroll(int value) {
           // Iterate through visible items and trigger onItemEntered for each
           QTreeWidgetItemIterator it(treeWidget);
           while (*it) {
               if (treeWidget->visualItemRect(*it).intersects(treeWidget->viewport()->rect())) {
                   // The item is currently visible
                   onItemEntered(*it, 0);
               }
               ++it;
           }
       }
    
    private:
       QTreeWidget *treeWidget;
    };
    
    int main(int argc, char *argv[]) {
       QApplication a(argc, argv);
       MyWindow w;
       w.show();
       return a.exec();
    }
    
    
    sierdzioS Offline
    sierdzioS Offline
    sierdzio
    Moderators
    wrote on last edited by
    #6

    You are not loading anything in fetchMore(), you still do full loading in the constructor of your model. So you will not gain anything this way.

    (Z(:^

    J 1 Reply Last reply
    1
    • JonBJ JonB

      @jinming
      Displaying half a million records in a treeview is not a great idea.

      J Offline
      J Offline
      jinming
      wrote on last edited by
      #7

      @JonB said in QTreeView memory consumption increasing:

      @jinming
      Displaying half a million records in a treeview is not a great idea.

      You are right,but my app is always reading data from USB device like CAN Card.I need alway display the last receive data in a UI, so people can know what is last data in CAN bus,.You know the data from USB device is growing by the time,so I think the MVC model is suitable and I select TreeView,but TreeView uses large memory likely.

      JonBJ 1 Reply Last reply
      0
      • J jinming

        @JonB said in QTreeView memory consumption increasing:

        @jinming
        Displaying half a million records in a treeview is not a great idea.

        You are right,but my app is always reading data from USB device like CAN Card.I need alway display the last receive data in a UI, so people can know what is last data in CAN bus,.You know the data from USB device is growing by the time,so I think the MVC model is suitable and I select TreeView,but TreeView uses large memory likely.

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

        @jinming
        I was just making an observation that (a) if you show half a million records in a tree view it's likely to cost quite some memory and (b) I wonder how accessible/useful that many records in a widget is to the end user.

        Maybe you will have to "prune" some of the older records as you go along and the new ones arrive to keep the total number lower. Or only create the (deeper) tree nodes "on demand" as the user actually interacts with the tree and expands parent nodes.

        J 1 Reply Last reply
        0
        • JoeCFDJ JoeCFD

          @jinming Jon is right. Better to display on demand. It is unnecessary to add all of them all in once.

          #include <QApplication>
          #include <QMainWindow>
          #include <QTreeWidget>
          #include <QTreeWidgetItem>
          #include <QScrollBar>
          #include <QVBoxLayout>
          
          class MyWindow : public QMainWindow {
             Q_OBJECT
          
          public:
             MyWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
                 treeWidget = new QTreeWidget(this);
                 treeWidget->setColumnCount(1);
                 treeWidget->setHeaderLabels({"Items"});
          
                 setCentralWidget(treeWidget);
          
                 // Connect the itemEntered signal to the slot
                 connect(treeWidget, &QTreeWidget::itemEntered, this, &MyWindow::onItemEntered);
          
                 // Populate the initial items
                 populateTree();
          
                 // Connect the scroll bar value changed signal to the slot
                 connect(treeWidget->verticalScrollBar(), &QScrollBar::valueChanged, this, &MyWindow::onVerticalScroll);
             }
          
             void populateTree() {
                 // Add some top-level items
                 for (int i = 0; i < 50; ++i) {
                     QTreeWidgetItem *topItem = new QTreeWidgetItem(treeWidget, QStringList() << "Top Item " + QString::number(i));
                     // Add a dummy child item to make the parent item expandable
                     new QTreeWidgetItem(topItem, QStringList() << "Loading...");
                 }
             }
          
          public slots:
             void onItemEntered(QTreeWidgetItem *item, int column) {
                 // Check if the item already has child items (the dummy item for loading)
                 if (item->child(0) && item->child(0)->text(0) == "Loading...") {
                     // Remove the dummy item
                     delete item->takeChild(0);
                     // Load and add the actual child items
                     for (int i = 0; i < 3; ++i) {
                         new QTreeWidgetItem(item, QStringList() << "Child Item " + QString::number(i));
                         // Add more child items or load data as needed
                     }
                 }
             }
          
             void onVerticalScroll(int value) {
                 // Iterate through visible items and trigger onItemEntered for each
                 QTreeWidgetItemIterator it(treeWidget);
                 while (*it) {
                     if (treeWidget->visualItemRect(*it).intersects(treeWidget->viewport()->rect())) {
                         // The item is currently visible
                         onItemEntered(*it, 0);
                     }
                     ++it;
                 }
             }
          
          private:
             QTreeWidget *treeWidget;
          };
          
          int main(int argc, char *argv[]) {
             QApplication a(argc, argv);
             MyWindow w;
             w.show();
             return a.exec();
          }
          
          
          J Offline
          J Offline
          jinming
          wrote on last edited by
          #9

          @JoeCFD You are right,but my app is always reading data from USB device like CAN Card.I need alway display the last receive data in a UI, so people can know what is last data in CAN bus,.You know the data from USB device is growing by the time,so I think the MVC model is suitable and I select TreeView,but TreeView uses large memory likely.
          You give me a idea about each time display 50 item's data in large data.The problem is when vertical scroll bar changing, I need update the 50 items display.

          jsulmJ 1 Reply Last reply
          0
          • JonBJ JonB

            @jinming
            I was just making an observation that (a) if you show half a million records in a tree view it's likely to cost quite some memory and (b) I wonder how accessible/useful that many records in a widget is to the end user.

            Maybe you will have to "prune" some of the older records as you go along and the new ones arrive to keep the total number lower. Or only create the (deeper) tree nodes "on demand" as the user actually interacts with the tree and expands parent nodes.

            J Offline
            J Offline
            jinming
            wrote on last edited by
            #10

            @JonB said in QTreeView memory consumption increasing:

            @jinming
            I was just making an observation that (a) if you show half a million records in a tree view it's likely to cost quite some memory and (b) I wonder how accessible/useful that many records in a widget is to the end user.

            Maybe you will have to "prune" some of the older records as you go along and the new ones arrive to keep the total number lower. Or only create the (deeper) tree nodes "on demand" as the user actually interacts with the tree and expands parent nodes.

            Yes, I need make some policy on QTreeView, for example, QTreeView only displays 1024 item, I need custom vertical scroll bar to select 1024 item data from the large data.

            1 Reply Last reply
            0
            • J jinming

              @JoeCFD You are right,but my app is always reading data from USB device like CAN Card.I need alway display the last receive data in a UI, so people can know what is last data in CAN bus,.You know the data from USB device is growing by the time,so I think the MVC model is suitable and I select TreeView,but TreeView uses large memory likely.
              You give me a idea about each time display 50 item's data in large data.The problem is when vertical scroll bar changing, I need update the 50 items display.

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #11

              @jinming said in QTreeView memory consumption increasing:

              I need alway display the last receive data in a UI

              But not ALL the data received so far, right?

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              J 1 Reply Last reply
              0
              • sierdzioS sierdzio

                You are not loading anything in fetchMore(), you still do full loading in the constructor of your model. So you will not gain anything this way.

                J Offline
                J Offline
                jinming
                wrote on last edited by
                #12

                @sierdzio said in QTreeView memory consumption increasing:

                You are not loading anything in fetchMore(), you still do full loading in the constructor of your model. So you will not gain anything this way.

                In the constructor, I just make the ready data and lazy loading by vertical scroll bar.
                In the rowCount function, I just return the loadCount.I think it works.

                int TreeModel::rowCount(const QModelIndex &parent) const
                {
                    TreeItem *parentItem;
                
                    if (parent.column() > 0)
                        return 0;
                
                    if (!parent.isValid())
                    {
                        parentItem = rootItem;
                        return loadCount;
                    }
                    else
                    {
                        parentItem = static_cast<TreeItem*>(parent.internalPointer());
                        return parentItem->childCount();
                    }
                }
                
                sierdzioS 1 Reply Last reply
                0
                • jsulmJ jsulm

                  @jinming said in QTreeView memory consumption increasing:

                  I need alway display the last receive data in a UI

                  But not ALL the data received so far, right?

                  J Offline
                  J Offline
                  jinming
                  wrote on last edited by
                  #13

                  @jsulm said in QTreeView memory consumption increasing:

                  @jinming said in QTreeView memory consumption increasing:

                  I need alway display the last receive data in a UI

                  But not ALL the data received so far, right?

                  It depends on the CAN baudrate,for example, if the baudrate is 500Kb/s, we will recive 4000 frames which DLC is 8 in every second. I need find a efficient way to display large data without the UI blocking. Maybe I need make some policy on QTreeView, for example, QTreeView only displays 1024 item, I need custom vertical scroll bar to select 1024 item data from the large data.

                  JoeCFDJ 1 Reply Last reply
                  0
                  • J jinming

                    @sierdzio said in QTreeView memory consumption increasing:

                    You are not loading anything in fetchMore(), you still do full loading in the constructor of your model. So you will not gain anything this way.

                    In the constructor, I just make the ready data and lazy loading by vertical scroll bar.
                    In the rowCount function, I just return the loadCount.I think it works.

                    int TreeModel::rowCount(const QModelIndex &parent) const
                    {
                        TreeItem *parentItem;
                    
                        if (parent.column() > 0)
                            return 0;
                    
                        if (!parent.isValid())
                        {
                            parentItem = rootItem;
                            return loadCount;
                        }
                        else
                        {
                            parentItem = static_cast<TreeItem*>(parent.internalPointer());
                            return parentItem->childCount();
                        }
                    }
                    
                    sierdzioS Offline
                    sierdzioS Offline
                    sierdzio
                    Moderators
                    wrote on last edited by
                    #14

                    @jinming said in QTreeView memory consumption increasing:

                    In the constructor, I just make the ready data

                    That is exactly the issue :-) You create all the objects in the constructor, thus taking a long time and a lot of RAM upfront.

                    With lazy loading the point is to defer (delay in time) initialising of the data until it is actually needed - when user scrolls close to it.

                    (Z(:^

                    J 1 Reply Last reply
                    0
                    • sierdzioS sierdzio

                      @jinming said in QTreeView memory consumption increasing:

                      In the constructor, I just make the ready data

                      That is exactly the issue :-) You create all the objects in the constructor, thus taking a long time and a lot of RAM upfront.

                      With lazy loading the point is to defer (delay in time) initialising of the data until it is actually needed - when user scrolls close to it.

                      J Offline
                      J Offline
                      jinming
                      wrote on last edited by
                      #15

                      @sierdzio said in QTreeView memory consumption increasing:

                      @jinming said in QTreeView memory consumption increasing:

                      In the constructor, I just make the ready data

                      That is exactly the issue :-) You create all the objects in the constructor, thus taking a long time and a lot of RAM upfront.

                      With lazy loading the point is to defer (delay in time) initialising of the data until it is actually needed - when user scrolls close to it.

                      The constructor is model, it is called once. My pointer is to test how memory the QTreeView uses to display large data, so I scroll the vertical scroll bar to watch the QTreeView memory increasing by Visual Studio IDE

                      1 Reply Last reply
                      0
                      • J jinming

                        @jsulm said in QTreeView memory consumption increasing:

                        @jinming said in QTreeView memory consumption increasing:

                        I need alway display the last receive data in a UI

                        But not ALL the data received so far, right?

                        It depends on the CAN baudrate,for example, if the baudrate is 500Kb/s, we will recive 4000 frames which DLC is 8 in every second. I need find a efficient way to display large data without the UI blocking. Maybe I need make some policy on QTreeView, for example, QTreeView only displays 1024 item, I need custom vertical scroll bar to select 1024 item data from the large data.

                        JoeCFDJ Offline
                        JoeCFDJ Offline
                        JoeCFD
                        wrote on last edited by
                        #16

                        @jinming if loading blocks UI, send loading to a thread.

                        1 Reply Last reply
                        0

                        • Login

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