PDA

View Full Version : PaintEvent - interupt paint



Talei
9th March 2014, 18:46
Hello,
I have a question regarding interruption of paint in paintEvent() / QPainter.

Basically what I want to achieve is stop / interrupting paint of QImage / QPixmap by QPainter.

What I do now is, in paintEvent() I paint QImage by QPainter. Everything works fine but I want to interrupt paint process so it would work like this:
- I paint current image next image paint is requested and I want interrupt paint and start painting next image.

My current "workflow" for image paint:
- [another thread] -> read image
- signal / slot to paint widget
- [main thread] paint widget in paintEvent by QPainter paints image
- user now can request another image so load do starts but now there is a "lag" because next image paint is started when current image is painted on.

to draw image I use .drawImage / .drawPixmap functions

Is there a way to achieve that?

Thanks in advance for reply.

ChrisW67
9th March 2014, 20:15
"User can now request another image to load"

The "user" is not human being right? You are saying that, using another thread (that cannot be running a Qt GUI) the user is locating an image, selecting it, and notifying the GUI thread of the program in less time than it takes the paintEvent() to draw the entire screen. Since this painting typically takes in the order of 1 or 2 milliseconds I do not see how this is achievable by the user. Perhaps you can explain/show what your paint event is really doing.

Talei
9th March 2014, 21:03
Yes, You have right, my bad I had this situation in debug mode, not noticed it, in release repaint takes up to 3ms for 2k+ images. But still I would like to cancel paint request.

Situation is like this:

User press key i.e. "S" or use mouse wheel to request next image. Application load next image in separate thread (of course only image load part is in that thread, not Ui) if end is reached wrap up is in effect and first image is shown.

Now when user "spawns" i.e. mouse wheel to request next image then I can see that whole image is always displayed but In old Win32 app I can see that image draw is cancelled half way through and I can "feel" that that old win32 app is a little faster if it comes to the load next image.

ChrisW67
10th March 2014, 00:07
You can draw 300 complete images per second I don't know that "faster" is a useful goal.

To interrupt the painting in this fashion you would have to paint image line by line (or strip by strip) using the drawImage()/drawPixmap() source and target rectangles. Between each line you would check to see if a new image has arrived and terminate the paint event immediately rather than continuing. Apart from being more complicated this will be slower not faster.

Talei
10th March 2014, 01:16
Thank You for the reply.

I was thinking abut different approach maybe with "back buffer" one or VSYNC. If two frames are drawn within small interval with VSync off it's possible to start another draw before previous one has ended. I know that Qt has this feature turned on. Turning this off would allow to interrupt previous one. Or maybe with "back buffer" and swap of widgets?

Actual reason is to eliminate wait time for images around 3-5k. I did test this one and paint do take more then 20ms (varies of course) so if user has multiple images of that resolution and want go really fast thought gallery then it would defiantly feel like "lag". Of course alternative would be to paint only visible part but that is something that I would like not to implement (but probably will go with that approach).

ChrisW67
10th March 2014, 05:15
To be honest I fail to see an issue. 20 ms per image = 50 images per second. If they are panning through an image list that quickly then the user cannot expect to see every image in any meaningful anyway. Draw an image only if their is one waiting and new one has not arrived in the past, say, 100 msecs.