PDA

View Full Version : [QWidget] Save content to image on paintEvent



multimolti
5th July 2013, 00:23
Hey,

I'm visualizing some simulation results in a QWidget in a GUI app, and inside the QWidget I paint using QPainter. Now I want to save the simulation progress in a video file, so I wanted to start by saving a bitmap of each timestep.

My simple idea was:
- In my redraw function (called from the paintEvent), render the QWidget to a QPixmap and save that:

QPixmap pixmap(this->size());

this->render(&pixmap, QPoint(), QRegion(this->frameGeometry()));
pixmap.save("example.png");

But since render() seems to call the paintEvent again, and that painEvent calls the whole image capturing routine, I always get stuck in an infinite, recursive paintEvent call.

So my other idea was to save the bitmap from the thread that's actually outputting the simulation results and rendering them in my QWidget:

canvas->setGrid(*grid);
canvas->update();

canvas->saveFrame();
saveFrame contains the same code as above, but this doesn't work because "it is not safe to use pixmaps outside the GUI thread".

So what can I do here? Any way to get the current widget pixmap without re-rendering?? That would be perfect because rendering may be complex and take some time, so I want to capture the currently displayed content right away, without re-rendering.

Any ideas or help? Thanks!

ChrisW67
5th July 2013, 01:03
Seems like this should work. In your paintEvent():

render the widget content to an off-screen QPixmap using a QPainter on the pixmap.
drawPixmap() onto the screen using QPainter on "this"
call QPixmap::save() which does not cause a redraw.

What effect the file operations will have on performance is entirely another issue.

multimolti
5th July 2013, 16:04
Nice, that worked perfectly! So far I don't see the performance drop too much, so I think I gonna use that method.

Thanks!