Reputation: 309
I am writing an app using QPainter and I need an analog of the cairo_push_group in the QPainter class to draw, say, a rectangle with bunch of holes in it, which may intersect.
The problem is that when I draw holes with the "clear" compose mode, everything is cleared underneath the holes I draw; I want the image, that was underneath the hole before I started drawing my complex shape, to stay. In other words - everything underneath the hole is cleared, when I just want everything underneath the hole to bee seen through.
One solution seems to be using the QPainterPath
with Odd fill option (the default one), but that does not suit me, as in my app the holes may intersect, and this way the two holes won't combine (the intersection of two holes is not a hole).
One more solution is to just to use the QPainterPath::subtracted
method, but for some reason it reduces the quality of polygons (circles become shapes with a countable number of sides, for example).
The other solution is to save the QImage
I am drawing on to a temporary QImage
, clear it, draw everything that I need and then using the "destination over" mode draw it again, but that seems to be a very slow and memory-consuming solution.
Is there any other solution to this problem? Maybe there IS an analog of the cairo_push_group function in Qt?
Please don't advice me to switch to cairo.
Pictures explain the problem better:
Upvotes: 1
Views: 257
Reputation: 309
I've found anwser myself.
One way one can do it is to still use the QPainterPath
+= and -= operators (which are identical to the QPainterPath::united
and QPainterPath::subtracted
methods), but without any bezier curves. I've replaced all the arcs, circles, etc. with "polylines" (for example, every circle is replaced with a 100-sided polygon). You can achieve any quality you need just by changing the number of sides etc.
The other solution - with the temporary QImage
- seems to be not too slow and works just okay. This is the way it is done in cairo also. Just create a QImage
with the same size asthe original, a QPainter
with the same settings as the original one and use the new QPainter
to draw on the temporary image, and, finally, use the QPainter::drawImage
method to draw everything on the original device.
Upvotes: 1