[Qt-interest] QTreeView and custom QAbstractItemModel performance problem
Felix Brack
fb at ltec.ch
Thu Jul 8 16:09:52 CEST 2010
On 08.07.2010 12:50, Andreas Pakulat wrote:
> 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
>
The removal operation in my AppendRow() function is only executed when
there are more rows then m_nMaxRows. Setting m_nMaxRows to 200 however
shows that the performance breakdown and the excessive CPU load occurs
way before a row has to be removed (starting at approximately 20 rows).
Well,I just changed my data() function to look as follows:
QVariant CMultiColumnListModel::data(const QModelIndex& Index, int
nRole) const
{
// sanity check
if (!Index.isValid()) {
return QVariant::Invalid;
}
if (nRole==Qt::DisplayRole) {
// return text data
return QString("Test");
}
// we do not support other roles for now
return QVariant::Invalid;
}
I know it is stupid but I can't think of a faster data() function. As I
expected the problem is exactly the same: very slow with 100 rows and a
CPU load of more then 50%.
More information about the Qt-interest-old
mailing list