PDA

View Full Version : Huge number of images inside a panel



torsak
13th October 2013, 22:34
Hello,

I am pretty new to Qt, and I am trying something I don't have enough experience to do without any advice.
I want to do display the progress of a download task that can be processed by several threads in parallel. In order to do that I would like to display a list of blocks (each block representing a few kilobytes of data) that would turn from grey to blue when the block has been downloaded. For those who know the download manager Flashget, this is very similar to what this piece of software does: here is a screenshot http://screenshots.fr.sftcdn.net/fr/scrn/59000/59014/flashget-portable-15.jpg

Because the file can potentially reach several gigabytes (this means that there can be several millions blocks to display), doing with without any performance issues is tricky.
I tried creating as many QPixmap instances as needed, but the ui is definitely too slow, even when I do not use a layout and set their geometry myself.

I feel like there are some optimizations that could be done (the blocks do not need to interact with the user, they can only have two colors, the size is fixed... maybe i could display a big image and set the pixel colors myself whenever a block changes its color?) but i am too new to Qt to know the best way to go. Too bad that Flashget is not open source, because there is no performance issues even with huge files.
I am using QT5 under Ubuntu with QT Creator.

Could you give me some pointers?
Thanks.

ChrisW67
13th October 2013, 23:20
A million widgets, i.e. QLabels containing QPixmaps in a QScrollArea, is unthinkable.

Things to think about:

I am almost certain Flashget and your average defrag utility limit total number of progress blocks and make the amount of data represented by each variable.
You only need to worry about as many progress blocks as will fit in the user's display. You certainly do not need to hold a pixmap for blocks that cannot be seen. There're only two
You could draw into a single image that you place into a QLabel and QScrollArea (as you suggest).
A custom widget could draw the blocks (in paintEvent()) that correspond to the current viewport based on an internal bitmap representing the on/off state of each.

torsak
15th October 2013, 22:43
Thanks for your reply.
Can you clarify what you meant in your second point? I would especially like to know the end of the sentence "There's only two..."

Actually drawing into a single image is not feasible, because the size of the image would be very big.

I guess the only option will be to listen to the scrollbar events and draw only what i need to display (as you mentionned in your points 2 and 4).
I will try to find some examples on the internet and hope it will not be too complex to implement.

ChrisW67
15th October 2013, 23:48
I started to write: There are only two distinct pixmaps involved, one for "on" and one for "off", so even several thousand pixmaps will share the data internally through Qt implicit sharing. Don't create a distinct pixmap for each block: assign from two static pixmaps so that sharing can do its thing.

A 1000x1000 image is not that large and represents 1e9 bytes if each pixel maps to 1000 bytes.

torsak
17th October 2013, 23:09
Thanks for your answer. I implemented a custom widget displaying only the viewable blocks when the user moves a scrollbar, without any performance issue whatever the size of the file is.