QTreeWidget performance after QtConcurrent
Hi,
I am using QtConcurrent for a function to process number of objects in batch.
For e.g. I have 1000 graphics objects, I call process() for 500 items and another call for remaining 500 items using two calls of QtConcurrent::run(...).
I get good performance improvement here. But after process() function I use these processed items to populate items in QTreewidget.
The time required to populate the QTreeWidget tremendously increases as compared to the time required for populating before we used QtConcurrent.
I have a XML file which contains details of each of these items which includes id, position, height, width. My application reads this file and pass this detail to process() to creates the Item class objects.
Code:
class Item :: QGraphicsObject
{
int m_iHeight, m_iWidth;
};
// process()
process(int iStart, int iEnd, <list of XMLNode>)
{
for(iStart to iEnd)
{
// Read XMLNode and create Item object using the read details
}
}
// read()
read()
{
// Read the XML File
QList<XMLNode> lstNodes = readXML();
// call process() for list of XMLNode
QList<Item*> lstItems = process(1, lstNodes.size(), lstNodes);
// Add these items to scene using m_scene->addItem((QGraphicsItem*) item);
// Iterate through the list of items and add each of the item to QTreeWidget
for(i = 0 to size )
{
Item* item = lstItems1.at(i);
treeItem->setText(0, tr(item->m_sId));
}
}
Below is the modified code using QtConcurrent::run()
Code:
// process()
QList<Item*> process(int iStart, int iEnd, <list of XMLNode>)
{
QList<Item*> lstItems;
for(iStart to iEnd)
{
// Read XMLNode and create Item object using the read details
// Move the created graphics object on main thread as it needs to be added to scene later
}
return lstItems;
}
read()
{
// Read the XML File
QList<XMLNode> lstNodes = readXML();
// call process() for list of XMLNode
int iSize = lstNodes.size();
QFutureSynchronizer<QList<Item*>> synchronizer;
QFuture<QList<Item*>> future1 = QtConcurrent::run(this, &Reader::process, 1, iSize/2, lstNodes);
QFuture<QList<Item*>> future2 = QtConcurrent::run(this, &Reader::process, iSize/2, iSize, lstNodes);
synchronizer.addFuture(future1);
synchronizer.addFuture(future2);
synchronizer.waitForFinished();
QList<Item*> lstItems1 = future1.result();
QList<Item*> lstItems2 = future2.result();
lstItems1.append(lstItems2);
// Add these items to scene using m_scene->addItem((QGraphicsItem*) item);
// Iterate through the list of items and add each of the item to QTreeWidget
for(int i = 0; i<= size; i++ )
{
Item* item = lstItems1.at(i);
treeItem->setText(0, tr(item->m_sId));
}
}
My problem is, previously populating the TreeWidget was taking less time (1.9 sec) for 1000 items but now when I used QtConcurrent for process(), it has been increased (21.5 sec) whereas calling process() using QtConcurrent takes less time.
Can you please guide me resolving this issue?
Re: QTreeWidget performance after QtConcurrent
Don't items one by one but rather do that in batches. For this you'll probably have to implement your own model and use QTreeView instead of QTreeWidget.
Re: QTreeWidget performance after QtConcurrent
Thanks Wysota.
Yes, I am planning to use QTreeView. But my concern here is the time has been substantially increased after i used QtConcurrent. Is that I have done something wrong here?
Re: QTreeWidget performance after QtConcurrent
I don't think this is caused by QtConcurrent. For instance line #35 of your code snippet does not make much sense and also line #40 is simply invalid (you should get a segfault once i == size. My wild guess would be that your tree widget's header is set to adjust its width to its contents which is very slow if you keep adding items one by one.