[Qt-interest] QTreeView and custom QAbstractItemModel performance problem

Felix Brack fb at ltec.ch
Fri Jul 9 16:41:57 CEST 2010


On 09.07.2010 15:24, Andre Somers wrote:
> On 9-7-2010 15:01, Felix Brack wrote:
>> On 07/09/2010 01:58 PM, Andre Somers wrote:
>>> On 9-7-2010 13:50, Felix Brack wrote:
>>>> On 09.07.2010 12:06, Andre Somers wrote:
>>>>> On 9-7-2010 11:57, Felix Brack wrote:
>>>>>> an
>>>>>> Well, I had no hasChildren() until now... My new hasChildren() looks
>>>>>> like this:
>>>>>>
>>>>>> bool CMultiColumnListModel::hasChildren(const QModelIndex& Parent)
>>>>>> const
>>>>>> {
>>>>>> return (QModelIndex()==Parent);
>>>>>> }
>>>>>>
>>>>>> Adding hasChildren() however does not change things with respect to
>>>>>> performance and CPU load.
>>>>>>
>>>>> If I understood you correctly, your model represents a table, right?
>>>>> That means: no children to any of the items.
>>>>>
>>>>> If so, why not just implement the above as:
>>>>>
>>>>> bool CMultiColumnListModel::hasChildren(const QModelIndex& Parent)
>>>>> const
>>>>> {
>>>>> Q_UNUSED(Parent)
>>>>> return false;
>>>>> }
>>>>>
>>>>>
>>>>> André
>>>>>
>>>> In fact it is a table, yes. There is one root item. All rows have the
>>>> root item as parent. Every row consist of the same number of columns.
>>>> The existence of a root item leads to my code of hasChildren().
>>>>
>>>> Felix
>>> Hmmm... I see.
>>>
>>> Would it be possible to ditch your root item and make it a real table?
>>> Or do you have other things in your view as well?
>>> Wouldn't it be faster to test Parent.isValid() instead of comparing with
>>> a newly constructed QModelIndex every time?
>>>
>>> André
>>>
>> You mean move from TreeView to TableView, right?
> No, I mean that instead of having all your record-nodes have parent
> node, get rid of that parent node and let all your records be nodes on
> their own. That way, you end up with a flat structure. If you inherit
> from QAbstractTableModel instead of QAbstractItemModel, that is what you
> will get.
>> I can (and probably
>> will) do that but it's really the last resort.
> Why? If you have a table, then what's wrong with using a QTableView?
By last resort I meant the following: before moving to TableView (which 
is of course not wrong at all) I would have liked to know why the 
decission for the TreeView was wrong, sort of learning to not make the 
same error twice or even more. What I know for sure: If I don't fix it 
(fixing means understanding what is wrong) it will bite me later (could 
be one of Murphy's laws...).
>> Furthermore when looking
>> at what the TableView can do I will have to switch off about everything.
>> For what I want the TableView is like taking sledgehammer to crack a
>> nut. I just want a protocol, say 200 lines, first column shows an icon
>> and when it's full the oldest data gets discarded.
> Well, you can also argue that QTreeView is a sledgehammer then: why do
> you need a whole infrastructure for keeping track of item trees, open
> and closed items, etc., if you just display a flat list anyway? And, do
> you really need multiple columns for what you do? A single column can
> contain both an icon and a text...
In short: I use the infrastructure because it is there. Of course I 
could create a widget and add rows and columns with data myself instead 
of using Qt's Model/View framework. I just thought it would be a good 
idea to use the framework offered by Qt, that assumption might be wrong.
I need multiple columns to arrange the according to preferences set by 
the user. Again you are right, I could do that by hand too.
>> As already stated: I don't think (I might be wrong of course) it is
>> performance problem of any function in the data model (including
>> hasChildren). The problem is the view requesting the same information
>> again and again from the data model. I have been able to prove this with
>> a very stupid data() function in an earlier post.
> I agree. The item views are not optimal in that sense. For instance,
> QListView will make *many* calls to the delegates sizeHint(), which in
> turn makes calls to the models data() and flags() and results in
> calculating text layouts (expensive operation), and then simply ignores
> the result! That is something that needs to be fixed in Qt. However,
> QTableView is much more efficient, as it does not by default ask for
> size hints because they are not used. You can make a table view look
> just like a tree view, if that's the issue.
That sounds like a very good explanation for what I am experiencing and 
what the profiler reports. It really seems that using a TreeView to do 
this was simply a wrong decision of mine. With this explanetion I think 
I can safely (with respect to learning about Qt's framework) discard my 
code and give the TableView a try. I will let you know about the outcome.
>> Of course this could be wrong; that would be the case if I missed to
>> implement a function in my data model that stops the view from queering
>> the same values again and again; that function however is not yet known
>> to me.
> Well, no, there is no such function. It all depends on the view, really.
> There are cases where implementing a function can help. Like if you use
> a QTreeView, it helps to implement hasChildren to return false. That
> will save you calls to childCount(), especially if the latter is not
> implemented as a call to childCount itself.
>
> The key is to choose the right view for your data, and to optimize it
> for your task. If your case, I don't see why you need a QTreeView. It is
> the most complicated view in the package, while QTableView is much
> simpler in terms of layout code. Some views can be tweaked with methods
> like setLayoutMode and setUniformItemSizes. They can boost performance a
> lot.
Agreed, see above...
>
> André
>
Felix



More information about the Qt-interest-old mailing list