PDA

View Full Version : Too slow adding & defining items to QTreeWidget



jnk5y
11th May 2006, 19:41
WinXP
QT4.0.1

The code below fills a QTreeWidget with items from a table in my database. I set the text so users can identify the name and set the WhatsThis to the id of the row so I know which one was selected by the user.

I'll take any advice to speed this up in any way. The table can have anywhere from 10-2000 entries. If i remove the text, WhatsThis, and icon it speeds things up by a factor of 10. This is really kicking my butt. Any help would be greatly appreciated.


query.exec( "SELECT name,number,id,identifier FROM table;" );

while( query.next() )
{
List << new QTreeWidgetItem(sectorsNode);
qString.sprintf("%s | %d" , query.value(0).toByteArray().data(), query.value(1).toInt() );
List .last()->setText( 0, qString );
List .last()->setWhatsThis( 0, query.value(2).toString() );
List .last()->setIcon( 0, Icon );
QApplication::processEvents();
}

jacek
11th May 2006, 20:02
Try this:
setUpdatesEnabled( false );
query.exec( ... );
while( query.next() ) {
// ...
}
setUpdatesEnabled( true );

jpn
11th May 2006, 20:04
- construct items without a parent (and store a pointer to the newly created item)
- access the item (to set text, whatsthis and icon) through the pointer, not by indexing the list
- add all items to a list
- add the list of items as children to the correct parent

Something like this:


QList<QTreeWidgetItem*> items;
while(...)
{
QTreeWidgetItem* item = new QTreeWidgetItem; // don't pass a parent here!
...
item->setText(...);
item->setWhatsThis(...);
item->setIcon(...);
items << item;
}
sectorsNode->addChildren(items);

jnk5y
11th May 2006, 20:17
jacek - Thank you. That did the trick!

jpn - I see what you are saying and yes that will definitely improve speed but I QTreeWidgetItem has no addChildren function only addChild

jpn
11th May 2006, 20:25
QTreeWidgetItem has no addChildren function only addChild
Right, seems that it was introduced in Qt 4.1. My bad.. ;)

jnk5y
11th May 2006, 20:47
Don't worry about it jpn :)

Actually just creating a pointer and defining it's properties and then adding it to the widget helped as much as setUpdatesEnabled( false ).

Together they make it super fast. I realize it must have had to redraw the table every time I made a change which would be = table size * 4.

If I ever get to upgrade addChildren will give me an even greater boost in speed.

Thanks to both of you.

jnk5y
12th May 2006, 22:05
Quick follow up about the QList<QTreeWidgetItem*>. Will deleting the main node delete the items inside for me? Or should i go through the list and delete each one and then delete the main node?

jpn
13th May 2006, 08:51
Quick follow up about the QList<QTreeWidgetItem*>. Will deleting the main node delete the items inside for me? Or should i go through the list and delete each one and then delete the main node?
Yes, all children get automatically deleted when the parent item is deleted. And all the items in the whole tree get automatically deleted when the tree widget is deleted. So not much cleanup actions are required..

Billy Lee Black
29th February 2008, 15:47
Hello guys!

I am also having a problem with QTreeWidget.

In my application, I sniff packages from a server and print them in the QTreeWidget as I receive them.

The problem is that after the QTreeWidget has many items, the insertion of new items becomes too slow and the cpu stays at 100%.

Is there any other kind of widget I can use instead of QTreeWidget to do this? I have to manage lots of items in the view.

Thanks

jacek
1st March 2008, 17:52
Is there any other kind of widget I can use instead of QTreeWidget to do this? I have to manage lots of items in the view.
You could try QTableView and a custom model. This way you can optimise item insertion to the maximum, but without any numbers it's hard to say whether it will be fast enough for you (some people reported 10x speed increase with custom model).

Billy Lee Black
1st March 2008, 18:09
You could try QTableView and a custom model. This way you can optimise item insertion to the maximum, but without any numbers it's hard to say whether it will be fast enough for you (some people reported 10x speed increase with custom model).

About the numbers, I am talking about 10.000 more items in the item view. It is just like the program Wireshark (Ethereal). So, I will need it very fast, because I am receiveing packages every time to show to the users.

But thanks for the tip. I will try the QTableView;)

Billy Lee Black
18th April 2008, 14:47
Well, I´ve made a custom Model and tried it with QTreeView and QTableView.

But both are still too slow even though my model is really simple.

In my application, I have like 8 columns in the view. I have to sniff network packets and print them in the view when I receive them. So, I am adding items to the view a lot of times, and each time I have to fill all the columns for each item added.

I really don't know anymore what to do. Will I have to implement a custom view too?:confused:

jacek
18th April 2008, 23:37
How do you add items to the model? One cell at a time or whole rows/subtrees?

Billy Lee Black
19th April 2008, 15:30
Well, I made a class that stores the data for all the columns of a row.

I set all the texts for the entire row and after that I add the row to the model.

wysota
19th April 2008, 20:52
Can we see the code?

Billy Lee Black
22nd April 2008, 16:16
This is my method for adding one item( a row ) to the tableview:


void AkViewItemModel::addItem(AkViewWidgetItem *newItem)
{
if(!newItem)
return;
int position = mItemsList.count();
beginInsertRows(QModelIndex(), position, position);
newItem->mViewWidget = mHeaderItem->akViewWidget();
mItemsList.append(newItem);
endInsertRows();
}

And below is the method to add a list of items:


void AkViewItemModel::addItems(QList<AkViewWidgetItem *> items)
{
int beginRow = mItemsList.count();
int numItems = items.count();
beginInsertRows(QModelIndex(), beginRow, beginRow+numItems-1);

AkViewWidgetItem *item = NULL;
for(int i = 0; i < numItems; i++)
{
item = items[i];
item->mViewWidget = mHeaderItem->akViewWidget();
mItemsList.append(item);
}
endInsertRows();
}

When I add a lot of single items, it is really slow! But if I accumulate some items in my application and then add them through a list, it becomes a lot faster and solves my problem.

Why are these methods beginInsertRows and endInsertRows so slow?

wysota
22nd April 2008, 20:26
These methods are not slow. But they cause some signals to be emitted and each emition triggers a redraw of all the views displaying the model. So if you add 100 items a second then your application is busy refreshing the views. That's why it's better to accumulate changes and update the model in chunks.