QTreeView memory consumption increasing
-
@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.
-
@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.
@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.
-
@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(); }
@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. -
@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.
@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.
-
@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.@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?
-
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.@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(); } }
-
@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?
@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.
-
@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(); } }
@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.
-
@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.
@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
-
@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.