How to insert many items into QListView without making the app freeze?
i have problem , i have app that gets input from web service , i poll info every 5 sec.
from the web service i generate items into QListView the problem is each insert i put something like
30-40 items with images and textboxs in each item. into the QListView .
now i know that the redraw and paint is heavy and cause the app to freeze.
but there must be some other strategy to make the item show without the freeze.
one idea i was thinking is:
set the items data in to container structure. and then in controlled way to insert the items one by one with a second delay between insert.
what do you think?
hi i don`t know if ure familiar with the concept of threads but they are very useful in that case...i recommend you to watch the videos from VoidRealms about it cause he explains simple and neat...
hope this helps! :http://www.youtube.com/playlist?list=PL2D1942A4688E9D63
Thanks but ....
sure i know thread and im using it , for example
im using thread to do the polling .
im talking about the case of painting allot of items at once into the widget
Do put the item generation into a "transaction"? That is: callBeginInsertRows() and endInsertRows() and do everything inbetween. I didn't test it myself, but the view should update only after the endInsertRows() call.
so you mean to move the insert to the listview?
today im adding the items in the model . like this :
this is in a loop in QStandardItemModel extended class:
@for ( items length ... )
// pWidget is my custom widget item
pWidget = new ItemWidget;
newItem = new QStandardItem;
newItem->setSizeHint( pWidget->size() );
//pDataListView is the listview
pDataListView->setIndexWidget( newItem->index(), pWidget );
so how should it be now ?
The problem is, that QStandardItemModel does not support the idea of a transaction: an operation in which you put in a lot of data at the same time, and you want to make that atomically. That's why I wrote my own item model in the past for cases where I did not want to create a QAbstractItemModel that operates on my store directly. That model supported such transactions by simply caching the list of modified, added and removed items, and sending the signals that contained the whole set of changes in one go. I think you will need something like that too.
Here's what I did (GPL code):
Thanks for sharing i will check this !
.. just look at it for few sec ..
tell do you have small tester to check it ? i dont what to go all over your code that using this ..
No, it is part of a much bigger project. I just refered to it as an example on how you could do this, not as a piece of ready to use code that you can just use in your project. This particular implementation depends on a matrix class that I wrote for that project as well, but that is just a class that makes a 2-d array looks nice.
Ok , i understand , i was thinking its component that can be used .
so if i understand you right , you basically cache all the items ? pre made empty items?
what if i like to use native Qt class's what should i use?
thanks for helping
I keep them in a memory structure, yes. So does QStandardItemModel. You can use any convenient memory structure. I already had a flexible matrix class in that project, so I decided to use it, but you can find plenty of alternatives. My version worked with QVariants to stay close to the QAIM API. If you want to use other types, you should considder if you should not rather create a real 'store' kind of object (-hierarchy) that provides a good, well structured API to access your data objects, and create a QAIM that works as an interface between that store and your item views.
-Another approach would be to subclass [[Doc:QAbstractListModel]] (you're using the model an a list view, right?) and reimplement the relevant methods. I'm with Andre here, what you need is not achievable with the QStandardItemModel with reasonable effort.-
I take that back. Looking at the snippet, I overlooked the setIndexWidget() call at first sight. One cannot speed up this much.
Thanks you both for the help . to understand it more .
@Volker what do you mean by :
"need is not achievable with the QStandardItemModel with reasonable effort."
what is wrong with the QStandardItemModel im using ?
what is not achievable with QStandardItemModel that i will need to implement with QAbstractListModel? the adding the items into memory ?
Thanks again .
With a subclass of the QAbstractXXXModels you can connect the webservice to the model directly. In that processing method you tell the model that you are going to change its contents, then you do the actual changes, then you tell the model that you're ready. This cannot be done from outside the model, as you would have to do with the QStandardXXXModels.
But I read back and noticed, that you use setIndexWidget(). This isn't handled by the models at all, but only by the view. So you cannot speed up things by using another model class here.
Ah, I missed the use of that method as well. Sorry.
All bets are off. It is a wart on the face of the model view framework, and it makes sure the whole thing is basically useless. Putting more and more widgets on your view is never, ever going to be fast. Sorry.
what if i set up like 100 widget items in the Init , when i start the app
and set them to be hidden , and when i get the info to fill them i just show the right widget items? ( i need only like 100 or 150 to be present in view)
In your case, I would consider using a [[Doc:QScrollArea]] with a [[Doc:QVBoxLayout]], as that is more or less visibly the same as a list view consisting only of widgets.
Do you really, really need to have actual widgets?
what is wrong with me inserting the widgets into the Treeview?
using QScrollArea will be faster?
Andre , i asked this and other forums before but i could find solutions to
things like making label with mouse select text for copy when i tried to use
I would go with a scroll area here, instead of a list view.
thanks , but why?
Because the item views are a bit imperformant when using many item widgets. That's not the main usage they were designed for.