[Solved] Model/View setIndexWidget() performance issue.
I have a listView to which widgets are added using "setIndexWidget()":http://qt-project.org/doc/qt-5.0/qtwidgets/qabstractitemview.html#setIndexWidget , The widget is displayed in the view but if I add many items to the list then it becomes too slow.
For eg :
@for (int i=0; i<500; i++)
QStandardItem *item = new QStandardItem(QString("Item %1").arg(i));
QModelIndex index = model->indexFromItem(item); listView->setIndexWidget(index,new QPushButton("Hello World"));
This takes around 15 sec to display. However if I don't use setIndexWidget() and just create an instance of QPushButton it takes no time to display.
What approach should I follow to avoid my application from freezing. I am thinking of adding a delegate that uses QStyle to render the look of a widget and in the edit mode it will display the actual widget.
Do you think about lazy loading model?
[quote author="qxoz" date="1361513704"]Do you think about lazy loading model?[/quote]
Can you provide an example for reference.
I never do that and never seen solution like this but the idea is:
Set widget for a item which in a visible area and remove widget when it out of scope visible area. but now i see that your solution of "adding a delegate that uses QStyle to render the look of a widget and in the edit mode it will display the actual widget" is more convinient.
Thanks for the help,
I still have a question about why setIndexWidget() makes the application freeze for a large data set .
There should be some workaround for this situation, I think I should file a bug report for this problem.
Probably it is not a bug, but a architecture limitations. Any way, file a bug report, so we get the opinions of Qt developers :)
So far its good , implemented as discussed and works as expected.
Is there anyway I can grab the image of the item in the listView, Currently I am painting the item using the delegate.
Finally implemented as required, this is solved.
That's great! How you solve it? Can you share some experience :)
Well I filed a bug report "QTBUG-29847":https://bugreports.qt-project.org/browse/QTBUG-29847?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel#issue-tabs but there was no update on that. For my requirements the listView size is fixed , so i am using a delegate that paints/renders the look of actual widget with data(stored in a class) and when there is a mouseClick on the item the actual widget is displayed using openPersistentEditor() at that index.
After making the changes/selection the data is saved and the editor is closed. For the model i'll still consider going for lazy loading approach.
Got a reply for the bug report
bq. J-P Nurmi added a comment - 05/Mar/13 1:22 PM
bq. One of the important aspects of the model-view framework in Qt is to represent the model data in a single widget (the view), using light weight "items" instead of huge amounts of heavier child widgets.
bq. While QAbstractItemView::setIndexWidget() is a convenient way to glue arbitrary widgets on top of certain item view items, it should not be abused to fill the whole view full of widgets. This would effectively kill the benefits of using the model-view framework in the first place. A list or grid of widgets is more effectively implemented as a simple layout of widgets.
bq. An effective way to implement clickable buttons within QAbstractItemView is to implement a custom item delegate and use QStyle to draw the button.
can you share the code snippet in paint method of delegate, now, even i have the same problem of performance taking a toll as i was trying to populate the same way you do. thanks in advance.