The example program on this page may be used, distributed and modified
without limitation.
Painting on the Desktop
The desktop demo contains three routines, each of which draws
something on the desktop. It does some nice stuff with QPainter,
and also demonstrates how one can treat the desktop as a widget like
any other.
//
// Qt Example Program: desktop
//
// Demonstrates that the desktop can be painted, just like any other
// widget.
//
#include <qimage.h>
#include <qbitmap.h>
#include <qpainter.h>
#include <qapp.h>
#include <stdio.h>
static double seed = 0.353535353535;
static const int KINDA_RAND_MAX = 32767;
static int kindaRand()
{
seed = seed*147;
seed = seed - (double) ((int) seed);
return (int) ( seed*(KINDA_RAND_MAX + 1) );
}
static int velocity( int i ) // change velocity
{
const int velmax = 15;
const int velmin = 4;
if ( i == 1 || i == 2 )
i = (kindaRand()&0x7fff % velmax)/3 + velmin;
else
i = (kindaRand()&0x7fff % velmax) + velmin;
return i;
}
//
// Draw polygon on desktop.
//
void poly()
{
QWidget *d = QApplication::desktop();
d->setBackgroundColor( white ); // white desktop
const int maxpoints = 5;
const int maxcurves = 8;
static int xvel[maxpoints];
static int yvel[maxpoints];
int head = 0;
int tail = -maxcurves + 2;
QPointArray *a = new QPointArray[ maxcurves ];
register QPointArray *p;
QRect r = d->rect(); // desktop rectangle
int i;
for ( i=0; i<maxcurves; i++ )
a[i].resize( maxpoints );
p = &a[0];
for ( i=0; i<maxpoints; i++ ) { // setup first polygon points
p->setPoint( i, (kindaRand()&0x7fff) % r.width(),
(kindaRand()&0x7fff) % r.height() );
xvel[i] = velocity(i);
yvel[i] = velocity(i);
}
QPainter paint;
paint.begin( d ); // start painting desktop
for ( int ntimes=0; ntimes<2000; ntimes++ ) {
paint.setBrush( QColor(kindaRand()%360, 180, 255, QColor::Hsv) );
paint.drawPolygon( a[head] );
if ( ++tail >= maxcurves )
tail = 0;
int minx=r.left(), maxx=r.right();
int miny=r.top(), maxy=r.bottom();
int x, y;
p = &a[head];
if ( ++head >= maxcurves )
head = 0;
for ( i=0; i<maxpoints; i++ ) { // calc new curve
p->point( i, &x, &y );
x += xvel[i];
y += yvel[i];
if ( x >= maxx ) {
x = maxx - (x - maxx + 1);
xvel[i] = -velocity(i);
}
if ( x <= minx ) {
x = minx + (minx - x + 1);
xvel[i] = velocity(i);
}
if ( y >= maxy ) {
y = maxy - (y - maxy + 1);
yvel[i] = -velocity(i);
}
if ( y <= miny ) {
y = miny + (miny - y + 1);
yvel[i] = velocity(i);
}
a[head].setPoint( i, x, y );
}
}
paint.end(); // painting done
delete[] a;
}
//
// Rotate pattern on desktop.
//
void rotate()
{
int i;
const int w = 64;
const int h = 64;
QImage image( w, h, 8, 128 ); // create image
for ( i=0; i<128; i++ ) // build color table
image.setColor( i, qRgb(i,0,0) );
for ( int y=0; y<h; y++ ) { // set image pixels
uchar *p = image.scanLine(y);
for ( int x=0; x<w; x++ )
*p++ = (x+y)%128;
}
QPixmap pm;
pm = image; // convert image to pixmap
pm.optimize( TRUE ); // rotation will be faster
QWidget *d = QApplication::desktop(); // w = desktop widget
for ( i=0; i<=360; i += 2 ) {
QWMatrix m;
m.rotate( i ); // rotate coordinate system
QPixmap rpm = pm.xForm( m ); // rpm = rotated pixmap
d->setBackgroundPixmap( rpm ); // set desktop pixmap
d->update(); // repaint desktop
}
}
//
// Generates a marble-like pattern in pm.
//
void generateStone( QPixmap *pm,
const QColor &c1, const QColor &c2, const QColor &c3 )
{
QPainter p;
QPen p1 ( c1, 0 );
QPen p2 ( c2, 0 );
QPen p3 ( c3, 0 );
p.begin( pm );
for( int i = 0 ; i < pm->width() ; i++ )
for( int j = 0 ; j < pm->height() ; j++ ) {
int r = kindaRand();
if ( r < KINDA_RAND_MAX / 3 )
p.setPen( p1 );
else if ( r < KINDA_RAND_MAX / 3 * 2 )
p.setPen( p2 );
else
p.setPen( p3 );
p.drawPoint( i,j );
}
p.end();
}
void drawShadeText( QPainter *p, int x, int y, const char *text,
const QColor &topColor, const QColor &bottomColor,
int sw = 2 )
{
if ( !p->isActive() )
return;
p->setPen( bottomColor );
p->drawText( x+sw, y+sw, text );
p->setPen( topColor );
p->drawText( x, y, text );
}
class DesktopWidget : public QWidget
{
public:
DesktopWidget( const char *s, QWidget *parent=0, const char *name=0 );
~DesktopWidget();
void paintEvent( QPaintEvent * );
private:
QPixmap *pm;
QString text;
};
DesktopWidget::DesktopWidget( const char *s, QWidget *parent, const char *name )
: QWidget( parent, name, WType_Desktop | WPaintDesktop)
{
text = s;
pm = 0;
}
DesktopWidget::~DesktopWidget()
{
delete pm;
}
void DesktopWidget::paintEvent( QPaintEvent * )
{
QColor c1 = backgroundColor();
QColor c2 = c1.light(104);
QColor c3 = c1.dark(106);
if ( !pm ) {
pm = new QPixmap( 64, 64 );
generateStone( pm, c1, c2, c3 );
setBackgroundPixmap( *pm );
update();
}
QRect br = fontMetrics().boundingRect( text );
QPixmap offscreen( br.width(), br.height() );
int x = width()/2 - br.width()/2;
int y = height()/2 - br.height()/2;
offscreen.fill( this, x, y );
QPainter p;
p.begin( &offscreen );
drawShadeText( &p, -br.x(), -br.y(), text, c2, c3, 3 );
p.end();
bitBlt( this, x, y, &offscreen );
}
void desktopWidget( const char *s = "Troll Tech" )
{
DesktopWidget *t = new DesktopWidget(s);
t->update();
qApp->exec();
delete t;
}
void desktopText( const char *s = "Troll Tech" )
{
const int border = 20;
QColor c1 = qApp->palette()->normal().background();
QColor c2 = c1.light(104);
QColor c3 = c1.dark(106);
QPixmap pm(10,10);
QPainter p;
p.begin( &pm );
QRect r = p.fontMetrics().boundingRect( s );
p.end();
int appWidth = qApp->desktop()->width();
int appHeight = qApp->desktop()->height();
if ( r.width() > appWidth - border*2 )
r.setWidth( appWidth - border*2 );
if ( r.height() > appHeight - border*2 )
r.setHeight( appHeight - border*2 );
pm.resize( r.size() + QSize( border*2, border*2 ) );
generateStone( &pm, c1, c2, c3 );
p.begin( &pm );
drawShadeText( &p, -r.x() + border, -r.y() + border, s, c2, c3 );
p.end();
qApp->desktop()->setBackgroundPixmap( pm );
}
//
// The program starts here.
//
int main( int argc, char **argv )
{
QApplication app( argc, argv );
if ( argc > 1 ) {
QFont f( "charter", 96, QFont::Black );
f.setStyleHint( QFont::Times );
app.setFont( f );
}
bool validOptions = FALSE;
if ( argc == 2 ) {
validOptions = TRUE;
if ( strcmp(argv[1],"-poly") == 0 )
poly();
else if ( strcmp(argv[1],"-rotate") == 0 )
rotate();
else if ( strcmp(argv[1],"-troll") == 0 )
desktopText();
else if ( strcmp(argv[1],"-trollwidget") == 0 )
desktopWidget();
else
validOptions = FALSE;
}
if ( argc == 3 ) {
validOptions = TRUE;
if ( strcmp(argv[1],"-shadetext") == 0 )
desktopText( argv[2] );
else if ( strcmp(argv[1],"-shadewidget") == 0 )
desktopWidget( argv[2] );
else
validOptions = FALSE;
}
if ( !validOptions ) {
fprintf( stderr, "Usage:\n\tdesktop -poly"
"\n\tdesktop -rotate"
"\n\tdesktop -troll"
"\n\tdesktop -trollwidget"
"\n\tdesktop -shadetext <text>"
"\n\tdesktop -shadewidget <text>\n" );
return 1;
}
return 0;
}
Generated at 13:30, 1998/01/15 for Qt version 1.32 by the webmaster at Troll Tech