[Qt-interest] QTreeView and custom QAbstractItemModel performance problem

Felix Brack fb at ltec.ch
Mon Jul 12 15:19:10 CEST 2010


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



More information about the Qt-interest-old mailing list