[Qt-interest] QTreeView and custom QAbstractItemModel performance problem

Andre Somers andre at familiesomers.nl
Fri Jul 9 15:24:19 CEST 2010


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?
> 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...
> 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.
> 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.

André

-- 
Nokia Certified Qt Developer.
Interested in Qt related job offers or freelance Qt consulting work.




More information about the Qt-interest-old mailing list