List Widget with icon view enabled - large number of images solution
In the program im currently working on I have a listwidget which displays the icons of the images the user adds in it.
The problem is that if the user e.g. add 1000 images with large resolution, the program will load for ever and ever and hard disk will go crazy (so will RAM) so as to load the thumbnails of these images inside the listwidget.
I am searching for a solution for this problem. I am thinking something like youtube does. If you search for something on youtube it will show you the thumbnails of the 1st videos but if you scroll down quickly you will notice that the thumbnails of the video below haven't been loaded and they do it live (probably to save bandwidth, in case you don't want to do a deep search and because probably most youtube users click on the 1st or 2nd video after a search)
I think that would be a nice solution, but then, what if the user load the pictures and scroll down to the last picture? The program will have to load all 1000 pictures at once, again? Then a timeout should be added, for examlpe, if an item is being shown more than 0.2 seconds, start loading its thumbnail or similar.
That's probably a solution, but I don't know where to start from, if you have any other ideas or any ideas on how to implement the above with a listwidget or other widget please let me know.
Thanks in advance!
First of all, you're going to need to use a QListView with a separate, custom QListModel subclass. That subclass should then at first return a default image as a placeholder for each image. However, when such a placeholder is displayed, a request should be put in a separate thread to load a thumbnail for the image in question. As soon as that thumbnail arrives, the thread signals the model, and the model signals the view via the dataChanged() signal that the data has changed for the item in question. That will replace the place holder image with the real thumbnail.
Furthermore, you should considder caching the generated thumbnails. The images are big, you say, so loading and then scaling them is going to be slow no matter what. Instead, you should probably store the generated thumbnails for later re-use. You can store them each as a separate file, or build up one big file with a whole bunch of thumbnails in one file with an index of where you can find what picture, that you need to load only once. That will be much faster.
Hello Andre, sorry for the laste response.
I don't know many things about subclassing but I'll try. I've already tried saving the thumbnails and it worked quite fine.
That's what I tried:
- Take image path
- replace all the "/" of the path with dots (".") and give a QString 'string' this value.
- Then do this:
//load picture from there, it has already been cached
QImage img; //etc, scale the image and save it to ~/.config/MyProgramsName/cache/, then load it from there. From there it will be available for later loads of the same picture as well
but, even if I've scaled all the images and then reload the exact same images, QFile::exists() is quite slow (the images I load are up to 1000).
But I assume this will be solved with the subclassing where the images will be loaded live while the user sees them and not altogether?
If you don't know about subclassing, I'd strongly like to suggest you take a step back, and head into your C++ books. Sorry, but it is really needed base knowledge to work effectively with Qt.
The caching of images will surely help, but as you say, hitting the file system so frequently also has its costs. Those costs will still exist even after you move to a multi-threaded, lazy loading approach. However, if you don't understand the c++ fundamentals involved, then I think implementing this approach is going to be a real issue for you. It is complicated enough when you do have the required basic programming skills, let alone if you have to gather those along the way...
Ok, gonna learn this stuff well :) Thanks. I'll post back if I came with any problem regarding qt!