PDA

View Full Version : How to efficiently display a large number of QPixmaps?



ChiliPalmer
3rd April 2011, 14:30
Hi,

I'm thinking about the best, most efficient way to display large numbers of QPixmaps.
I had several Ideas:

1. Store all the QPixmaps in a subclass of QWidget and in the paintEvent iterate over all those QPixmaps, calculate the right position for each and paint it.

2. Store the individual QPixmaps in a subclass of QWidget and use the paintEvent to paint the pixmap. Those objects would then be organized in a QGridLayout, which I would have to redo in a resizeEvent.

3. Store the individual QPixmaps in a small container Class (not a subclass of QWidget) and, within a subclass of QWidget, store them in a sort of dynamic GridLayout so that I wouldn't have to calculate the positions in each paintEvent.

What do you think? My main concern is efficiency on slower systems like tablets or small laptops, and a short delay when the QPixmaps are created and maybe when the window is resized would be allright, but not each time it's painted.

JohannesMunk
3rd April 2011, 16:41
Hi!

What is this for? A thumbnail browser?

1 vs 3) Calculating the positions for those pixmaps is going to be of NO importance for performance compared to the actual loading and drawing!

Do you have more pixmaps than will fit into memory? Then it will be difficult to load all the pixmaps into widgets and keep track of the memory usage. If you do the painting yourself you can use the global QPixmapCache to reload only when necessary.

If your individual pixmaps must be loaded and rescaled like they have to in a thumbnail browser you should consider loading them multithreaded and on demand.
I recently got aware of the Thinker-Qt-library: http://hostilefork.com/thinker-qt/ which introduces the appealing concept of a Thinker::Present/Watcher, that could return a placeholder until the loading is complete. And it allows to skip requests that became unnecessary later, like you have when the user scrolls while your program tries to load the appropriate pixmaps. I have not yet used it, but this would be a perfect match for such a scenario.

Depending on what you want to achieve on the long run, you might also consider using a QGraphicsScene. This would get you an easy (optional) access to OpenGL for faster painting.

HIH

Johannes

ChiliPalmer
4th April 2011, 01:05
Hi Johannes

Thank you very much so far.

Yes, I have a sort of Thumbnail Browser in mind. A few Pictures wouldn't be a problem, but I want to be able to display folders with several hundred pictures, too, without shutting down the system.
I guess a kind of fetchMore function would be sensible, to create QPixmaps from the files while scrolling, and store these QPixmaps up to a certain limit, maybe until the user has scrolled away far enough.

I don't have any experience with QGraphicsScene. I always thought that it's more suited to display dynamic, interactive content, not just something like thumbnails of files?

JohannesMunk
4th April 2011, 02:25
Hello!

A GraphicsScene would definitly be up to the task. And its definitly worth looking into! You would profit with some nice animations and effects. And you could implement cool stuff like magnifying the image below the mouse.

The way to go then, would be to implement a custom QGraphicsItem that represents one file. In its paintEvent you look if the pixmap is already loaded to the global QPixmapCache = if the local cache ident is valid... if not you dispatch a loading and rescaling request to your working thread pool and connect an item-update slot to its result-ready-signal. Did you take a look at Thinker-Qt?

One thing I have not figured out right now, is how you would stop a load operation, because the user scrolled out of the way.

Good look with your project,

Johannes