[Qt-interest] QTreeView and custom QAbstractItemModel performance problem

Andreas Pakulat apaku at gmx.de
Thu Jul 8 12:50:46 CEST 2010


On 08.07.10 11:51:38, Felix Brack wrote:
> On 08.07.2010 10:58, Andreas Pakulat wrote:
> > On 08.07.10 10:14:11, Felix Brack wrote:
> >> By subclassing QAbstractItemModel I have create a custom model that
> >> stores data from a communication trace row by row. Every row has
> >> multiple columns such as a time stamp, the data traced from the
> >> communication, etc. The number of rows in the data model is limited,
> >> let's say to 100 rows. When adding row 101 it is appended and the first
> >> row (i.e. the one with the oldest data) is removed.
> >>
> >> To show the information to the user I use a QTreeView which shows each
> >> row of the data in the model line by line, i.e. the model is not
> >> hierarchic, all rows have the same parent (root) and consist of multiple
> >> columns.
> >>
> >> Things are working so far but performance is very poor and the CPU load
> >> is incredible (even with just 100 rows). The reason for this is that
> >> whenever I append a row to the model the view calls the models 'data'
> >> member for all rows and all columns.
> >>
> >> It seems that I'm missing something fundamental here and that appending
> >> a row of data to my model looks for the view like the entire data has
> >> changed. I will have to change something so only the data from the newly
> >> append row is queried by the view.
> >>
> >> I just don't know how to do that... Can anybody push me into the right
> >> direction?
> >
> > Can you post your model implementation? It sure sounds like you're doing
> > the appending wrong, but without having a look at the code its not possible
> > to say what exactly is wrong.
> >
> > A blind guess could be that you're reset'ting you're model every time you
> > add a row instead of using begin/endInsertRows correctly. See the example
> > models in Qt.
> >
> > Also I'd suggest to use a QTableView instead of QTreeView as that one is
> > significantly faster on non-tree structures (you can tweak it to have no
> > lines etc.) in case you ever get more than 100 rows.
> 
> Hello Andreas,
> 
> Thanks for your response. The code below is my 'AppendRow' method. The 
> variable 'm_Data' and 'm_IconKey' are just arrays containing the textual 
> data as well as an icon that gets displayed in the first column.
> 
> QModelIndex CMultiColumnListModel::AppendRow(QString IconKey, 
> QStringList Data)
> {
>    beginInsertRows(QModelIndex(), m_Data.size(), m_Data.size()) ;
>    m_Data.push_back(Data);
>    m_IconKey.push_back(IconKey);
>    endInsertRows();
> 
>    if ((m_nMaxRows!=0) && ((int)(m_Data.size())>m_nMaxRows)) {
>      // remove oldest element from list
>      beginRemoveRows(QModelIndex(), 0, 0);
>      m_Data.erase(m_Data.begin());
>      m_IconKey.erase(m_IconKey.begin());
>      endRemoveRows();
>    }
> 
>    return index(m_Data.size()-1, 0);
> }
> 
> Do you see any problem here?

No, can't see anything obvious wrong. Could be the removal of the first
element is the culprit. In general the data() function of your model should
be as fast as humanly possible using as little computed data and as much
pre-computed data as you can get.

Andreas

-- 
Your motives for doing whatever good deed you may have in mind will be
misinterpreted by somebody.



More information about the Qt-interest-old mailing list