PDA

View Full Version : Custom shaped forms and controls



AlbertGoodwill
19th October 2007, 07:00
Hello,

Could some Qt expert please advise me how to create, custom shaped forms and controls (buttons and frames/panels) both in Linux and Windows?

Thanks,

Albert Goodwill

PS. By the term "Custom shaped" I mean non-rectangular, non-elliptical, with and/or without transparent regions, ie. arbitrary shaped forms which their shapes defined by a background image. (Like the Windows media player skins http://www.microsoft.com/windows/windowsmedia/player/skins.aspx , http://www.theskinsfactory.com/skinsfactory/ or like WinAmp skins http://www.winamp.com/skins)
See also:
Shaped Forms:
==========
http://www.abf-dev.com/krp-regions-library.shtml
http://torry.net/pages.php?id=94
http://www.byalexv.co.uk/index.html?VBSFC.html
http://www.onlytools.com/edgetracer/screenshot.htm
http://bcbjournal.org/articles/vol4/0002/Image_shaped_forms.htm?PHPSESSID=81c171871142feeca 2d5a5d664585d4f

Shaped Buttons:
===========
http://torry.net/pages.php?id=80
http://www.picsoft.de/compon.htm

kernel_panic
19th October 2007, 07:35
in qt you use setMask for this task normally.
if your shape is a pixmap than use


setMask(pixmap.mask());

to make the window semitransparent(on windows), look at the wiki in examples.
you can do it in another way, too.

if you use the ARGB window (from wiki),you can ask in the drawCtrl function for your button if its yours, you draw an pixmap instead of rendering the button. Here some code to do this.

For example in the right top you have a button called cl (for close):

paintEvent:


QPushButton *cl = findChild<QPushButton *>(QString("cl"));
if(QRegion(cl->geometry()).contains(mapFromGlobal(QCursor::pos()) ))
if(!cl->isDown())
clstate = 1;
else
clstate = 2;
else
clstate = 0;

drawCtrl:


if (!widget)
return QPixmap();
else if(widget->objectName() == "cl")
{
QPainter p(&widgetMask);
p.setRenderHint(QPainter::Antialiasing);
switch(clstate)
{
case 0:
p.drawPixmap(widget->geometry(), QPixmap(":/images/cl.png").copy(0,0,128,128));
break;
case 1:
p.drawPixmap(widget->geometry(), QPixmap(":/images/cl.png").copy(0,128,128,128));
break;
case 2:
p.drawPixmap(widget->geometry(), QPixmap(":/images/cl.png").copy(0,256,128,128));
break;
default:
p.drawPixmap(widget->geometry(), QPixmap(":/images/cl.png").copy(0,0,128,128));
break;
}
p.end();

}
else
widget->render(&widgetMask, widget->geometry().topLeft(), r, QWidget::DrawWindowBackground | QWidget::DrawChildren | QWidget::IgnoreMask);


with this you can simulate hover and pressed. Like i do here you have to do with every widget, you want to shape. The function of the widget is the same, just how it looks is different. this only works if you use argb widgets!