How to make qtreeview display 10 million pieces of data quickly with less memory consumption? This problem has bothered me for a long time. I have found a lot of relevant information on the Internet, but no reasonable solution has been found. Today, I will provide my solutions to my friends for everyone to learn from each other.
I started to use the qtreewidget control to display my data. I found that the control can still cope with displaying data below 10000 lines. However, if there are more than 10000 items, I can clearly feel that there will be a card when the screen is refreshed, and it takes up a lot of memory. Although the operation is simple and convenient, it is not as flexible as qtreeview. Because the amount of data I want to display is very large, even more than 10 million. Therefore, using qtreewidget to display is obviously unable to meet the performance requirements, so I plan to use qtreeview to display, not wordy, quickly get to the point. Let's talk about how I can quickly display 10 million pieces of data through qtreeview!
1. By reading the data to be displayed from the file and sending it to qtreeview for display, the problem of large memory consumption can be solved without reading the data to memory at one time.
2. We know that the data display is realized by refreshing. When refreshing, only the visible area of the screen is refreshed each time, and the other parts do not need to be refreshed, so as to solve the problem of slow display speed.
After solving the above two problems, there will be no problem in displaying 100 million pieces of data, and the display speed and memory occupancy are equivalent to displaying 1000 pieces of data, which sounds very attractive. Here is how I solve these two problems through qtreeview:
1. Overload the following functions in qabstractitemmodel:
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
QVariant data(const QModelIndex &index, int role) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;
(1)QVariant headerData(intsection, Qt::Orientationorientation, int role =Qt::DisplayRole)const; The title of the tree view is displayed. The section represents the column. Starting from 0, the orientation indicates the direction of the title (horizontal or vertical). The role of the role is QT:: displayrole, which indicates the display text. Of course, there are other roles. You can refer to the QT development manual. Example code:
QVariant CMyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
{
return pData->headerData(section);
}
return QVariant();
}
Display the horizontal header, where pdata is the object of a data class I defined, which I named CDATA here. Headerdata to retrieve the data to be displayed.
(2) Qvariant data (const qmodeldindex & index, int role) const; displays data. Index represents the tree node index, and each node in the tree has a corresponding index. When index = qmodeldindex(), it means that the node is the root node, otherwise it is a non root node. The index stores the location information (row and column) of the node in the same storage node, as well as the special information of the node, such as index.internalPointer (), this is a pointer through which we can save the node information we want. The role is the same as above. Example code:
QVariant CMyModel::data(const QModelIndex &index, int role) const
{
if (! index.isValid ())
return QVariant();
int row = index.row ();
int col = index.column ();
if(role == Qt::DisplayRole)
{
return pData->getData(row, col);
}
return QVariant();
}
Get the data to be displayed through GetData. The data side in our file only needs to read the data we want to display each time, and does not need to put all the data into the memory, so as to save the memory space, so as to solve the first problem mentioned above.
(3) Int rowcount (const qmodeldindex & parent = qmodeldindex()) const; it is not difficult to guess whether the function returns the number of child nodes under the parent node. Let's take a look at the example code:
int CMyModel::rowCount(const QModelIndex &parent)const
{
return pData->rowCount();
}
For the sake of simplicity, we don't consider the parent node here. We think that there are rowcount () nodes in any node.
(4) Int columncount (const qmodeldindex & parent = qmodeldindex()) const; returns the number of columns in the parent node, example code:
int CMyModel::columnCount(const QModelIndex &parent)const
{
return pData->colCount();
}
(5) Next, let's look at the implementation of qmodeldindex index (int row, int column, const qmodeldindex & parent = qmodeldindex()) const;:
QModelIndex CMChModel::index(int row, int column, const QModelIndex &parent) const
{
return createIndex(row, column, NULL);
}
This function is used to create the index of a node. Here, it is a bit simpler. Only one level node is created. If you want to create a multi-level node, you need to create the corresponding node through the data in the parent index (such as internalpointer()), and pass the specified index data to the node through the third parameter of createindex. Since I don't need to create multi-level nodes here, I pass in null. So how can we establish the parent-child relationship of nodes? You must have thought of it, qmodel index parent (const qmodel Index & Index) const; It is to establish the parent-child relationship of parent-child nodes. If there is only one layer of nodes, this function does not need to be overloaded. So far, our display data model has been implemented. Next, we need to show the model through the view (qtreeview).
Let's take a look at how qtreeview displays the model we built above. Look at a simple code, and you will understand:
QTreeView treeView;
CMyModel *pModel = new CMyModel();
treeView.setModel (pModel);
treeView.show ();
2. Is it very simple? Here we have finished the implementation of processing a large amount of data through qtreeview. When you prepare to process your large amount of data according to the above method, you will find that 10000 lines of data will be displayed or the card will be stuck. What is the reason? In fact, this has been bothering me for a long time. I haven't found any relevant information on the Internet. I have no choice but to gnaw at the source code of qtreeview. In fact, qtreeview does display visible data (1000 lines of data are displayed each time. Theoretically, 1000 lines are enough to occupy the computer screen. In this way, no matter how much data you have, I always take 1000 lines of data, so 100 million lines According to 1000 data display speed is the same, as long as you read only the data to be displayed at one time, the memory occupancy is the same). Since the problems have been solved, why will there be a card phenomenon?
After further research on the source code of qtreeview, it is found that the time-consuming part is that the row height of each row will be calculated when qtreeview is refreshed for the first time. In this way, when refreshing, it is necessary to traverse the data of all rows. The original card is located in this place. How should we solve this problem? The implementation method is very simple, that is, add one more line to the above code, treeView.setUniformRowHeights (true); in this way, the row height of all rows will not be refreshed and the problem of displaying large quantities of data with qtreeview has been solved.
Finally, we add that this implementation method can adapt to other qtableview, qlistview and other views.
http://blog.csdn.net/rabinsong/article/details/8452946
Qtreeview processes large amounts of data (uses 10 million pieces of data and only partially refreshes each time)
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.