Friday, August 04, 2006

Shadows

Some of the questions that I get quite a lot lately are: how do I make good looking shadows with Qt4? How do I make them from SVG's? Can you show me the code?

So to answer those question in general I wrote a small application that shows how to do shadows. There's couple of ways of getting the shadows look decently. The first step is getting a black rendering of whatever it is that you want to shadow. In this example we open a QPainter on the svg rendering that we want to shadow and we fill the entire area with black color. The trick is to set the composition operation to SourceAtop, which basically makes rendered area from the SVG black - exactly what we wanted. Once we have our rendering in black we can blur it. The code for the application along a couple of SVG's is here: http://ktown.kde.org/~zrusin/examples/shadows.tar.bz2. Finally images showing the results of our demo application follow:




4 comments:

Anonymous said...

Will it work outside of the window box? Like, can you add a shadow to a windowless logo and make the shadow appear on wallpaper/other windows below?

frerich said...

With Qt 4.1.4, clicking the spin box triggers Widget::paintEvent in an endless loop (I was wondering why my laptop became so warm and noticed the image kept repainting itself).

Widget::paintEvent takes roughyl 240ms here, 160ms of which are spent in the code which draws the black pixmap onto a QImage (just before that image is then blurred). Is this a driver issue? Such implicit image<->pixmap conversions make it feel really sluggish here.

Zack said...

@anonymous: yes with argb windows,

@frerich: no, it's not a driver issue. you should never ever do conversions between image and a pixmap on paintEvents, not for apps where rendering speed matters (and this one did not qualify as such, but if you have extra time on your hand i can't stop you from adding timers anywhere you want it's just that like in this case they'll be useless =) ).

Sergey said...

im using qt 4.5, windows.

if prepare release build and make program window small, shadow changes color from grey to another

bug is fixed, if make a change:

QImage img(shadow.width()+radius*2, shadow.height()+radius*2,
QImage::Format_ARGB32);

img.fill(Qt::transparent);