[Qt-interest] QTreeView and custom QAbstractItemModel performance problem

Felix Brack fb at ltec.ch
Thu Jul 8 11:51:38 CEST 2010


On 08.07.2010 10:58, Andreas Pakulat wrote:
> On 08.07.10 10:14:11, Felix Brack wrote:
>> Hello,
>>
>> 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.
>
> Andreas
>

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?

I will check your suggestion about using QTableView instead of QTreeView 
(will have to check if it can display an icon in the first column).

Felix



More information about the Qt-interest-old mailing list