[Qt-interest] QTreeView and custom QAbstractItemModel performance problem

Felix Brack fb at ltec.ch
Mon Jul 12 15:36:45 CEST 2010


On 12.07.2010 15:19, Felix Brack wrote:
> On 08.07.2010 10:14, 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?
>>
>> many thanks, Felix
>
> First of all I would like to thank all of you who pushed me into the
> right direction. This is in fact replacing the QTreeView by a
> QTableView. Besides the tweaking to make the table look like 'a list of
> rows with colums' it is really amazing how little one has to change at
> the code: thank you Qt!
> My model is still derived from QAbstrctItemModel which is absolutely ok
> even if the the view is a TableView.
>
> Here is what I did to make the table look more like a list with
> different columns:
>
> ui->listTrace->setShowGrid(false);
> ui->listTrace->setCornerButtonEnabled(false);
> ui->listTrace->setSelectionMode(QAbstractItemView::NoSelection);
> ui->listTrace->verticalHeader()->setHidden(true);
> ui->listTrace->verticalHeader()->setResizeMode(QHeaderView::Fixed);
> ui->listTrace->verticalHeader()->setDefaultSectionSize(16);
> ui->listTrace->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
>
> ui->listTrace->horizontalHeader()->setStretchLastSection(true);
> ui->listTrace->horizontalHeader()->setClickable(false);
> ui->listTrace->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);
>
> I admit these are a few more lines then with the TreeView but it's worth
> the price. There are just two tiny little things I did not manage to
> tweak until now.
>
> 1. I can still click an item (any row/column) and it gets rendered
> with a dotted box around it. This is not the selection of the item
> since I disabled item selection.
> 2. If I have, say 20 visible rows, the 'ResizeToContents' does not
> happen until I add an additional row, i.e. the view has to scroll.
> If I call resizeColumnsToContents() manually whenever I add a row
> resizing works from the beginning (i.e. starting with the first row
> I add).
>
> If I mange to eliminate those two 'issues' the view would look perfect.
> Any hint about this?
>
> Many thanks again, Felix

Solved the first issue, it was the focus, by adding the following:

ui->listTrace->setFocusPolicy(Qt::NoFocus)

Felix



More information about the Qt-interest-old mailing list