#!/usr/bin/perl -w # # PerlQt Example Application: drawdemo # # Demonstrates the painter and the printer. # use Qt 2.0; use POSIX 'math_h'; # No atan() in Perl. # # This function draws a color wheel. # The coordinate system x=(0..500), y=(0..500) spans the paint device. # sub drawColorWheel { my $p = shift; my $f = Qt::Font->new('Times', 18, Qt::Font::Bold); $p->setFont($f); $p->setPen(Qt::black); $p->setWindow(0, 0, 500, 500); for(my $i = 0; $i < 36; $i++) { my $matrix = Qt::WMatrix->new; $matrix->translate(250.0, 250.0); $matrix->shear(0.0, 0.3); $matrix->rotate($i*10); $p->setWorldMatrix($matrix); $c = Qt::Color->new; $c->setHsv($i*10, 255, 255); $p->setBrush($c); $p->drawRect(70, -10, 80, 10); $p->drawText(80+70+5, 0, "H=" . $i*10); } } # # This function draws a few lines of text using different fonts. # { my @fonts = ('Helvetica', 'Courier', 'Times'); my @sizes = (10, 12, 18, 24); sub drawFonts { my $p = shift; my($y) = (0, 0, 0); for my $f (@fonts) { for my $s (@sizes) { my $font = Qt::Font->new($f, $s); $p->setFont($font); my $fm = $p->fontMetrics(); $y += $fm->ascent(); $p->drawText(10, $y, "Quartz Glyph Job Vex'd Cwm Finks"); $y += $fm->descent(); } } } } # # This function draws some shapes # sub drawShapes { my $p = shift; my $b1 = Qt::Brush->new(Qt::blue); my $b2 = Qt::Brush->new(Qt::green, Qt::Dense6Pattern); my $b3 = Qt::Brush->new(Qt::NoBrush); my $b4 = Qt::Brush->new(Qt::CrossPattern); $p->setPen(Qt::red); $p->setBrush($b1); $p->drawRect(10, 10, 200, 100); $p->setBrush($b2); $p->drawRoundRect(10, 150, 200, 100, 20, 20); $p->setBrush($b3); $p->drawEllipse(250, 10, 200, 100); $p->setBrush($b4); $p->drawPie(250, 150, 200, 100, 45*16, 90*16); } # # This function draws a text that follows a (Bezier) curve. # Notice that this function does not support the general case. # It should be rewritten to calculate the real dx/dy. # sub drawPathText { my $p = shift; my $a = Qt::PointArray->new(4); $a->setPoint(0, 100,200); $a->setPoint(1, 150,75); $a->setPoint(2, 250,75); $a->setPoint(3, 300,200); $a = $a->quadBezier(); $p->setPen(Qt::lightGray); $p->drawPolyline($a); $p->setFont(Qt::Font->new('Times', 24)); $p->setPen(Qt::black); my $text = "PerlQt rocks!"; my $len = length($text); return unless $len; my $ipos = 2; # $a->size()/$len; # ugly hack, fix me my $cpos = $ipos; for(my $i = 0; $i < $len; $i++) { my $p1 = $a->point($cpos-1); my $p2 = $a->point($cpos+1); my $pt = $a->point($cpos); my $dx = $p2->x() - $p1->x(); my $dy = $p2->y() - $p1->y(); my $angle = atan($dy/$dx); $angle *= 180.0/3.14; my $m = Qt::WMatrix->new; $m->translate($pt->x(), $pt->y()); $m->rotate($angle); $p->setWorldMatrix($m); $p->drawText(0, 0, substr($text, $i, 1), 1); $cpos += $ipos; } } package DrawView; use Qt 2.0; use Qt::slots 'updateIt(int)', 'printIt()'; @ISA = qw(Qt::Window); @ourDrawFunctions = ( { f => \&main::drawColorWheel, name => 'Draw color wheel' }, { f => \&main::drawFonts, name => 'Draw fonts' }, { f => \&main::drawShapes, name => 'Draw shapes' }, { f => \&main::drawPathText, name => 'Draw path text' } ); # # Construct the DrawView with buttons. # sub new { my $self = shift->SUPER::new; $self->setCaption("PerlQt Draw Demo Application"); $self->setBackgroundColor(Qt::white); my $printer = Qt::Printer->new; # Create a button group to contain all buttons my $bgroup = Qt::ButtonGroup->new($self); $bgroup->resize(200, 200); $self->connect($bgroup, 'clicked(int)', 'updateIt(int)'); # Calculate the size for the radio buttons my $maxwidth = 80; my $i; my $n; my $fm = $bgroup->fontMetrics(); for($i = 0; $i < @ourDrawFunctions; $i++) {#$i (0 .. $#ourDrawFunctions) { $n = $ourDrawFunctions[$i]{'name'}; my $w = $fm->width($n); $maxwidth = $w > $maxwidth ? $w : $maxwidth; } $maxwidth += 20; for($i = 0; $i < @ourDrawFunctions; $i++) { $n = $ourDrawFunctions[$i]{'name'}; my $rb = Qt::RadioButton->new($n, $bgroup); $rb->setGeometry(10, $i*30+10, $maxwidth, 30); $rb->setChecked(1) if $i == 0; } my $drawindex = 0; my $maxindex = $i; $maxwidth += 40; # Create and setup the print button my $print = Qt::PushButton->new('Print', $bgroup); $print->resize(80, 30); $print->move($maxwidth/2 - $print->width()/2, $maxindex*30+20); $self->connect($print, 'clicked()', 'printIt()'); $bgroup->resize($maxwidth, $print->y()+$print->height()+10); $self->resize(640, 300); @$self{'printer', 'bgroup', 'print', 'drawindex', 'maxindex'} = ($printer, $bgroup, $print, $drawindex, $maxindex); return $self; } # # Called when a radio button is clicked. # sub updateIt { my $self = shift; my $index = shift; if($index < $self->{'maxindex'}) { $self->{'drawindex'} = $index; $self->update(); } } # # Calls the drawing function as specified by the radio buttons. # sub drawIt { my $self = shift; my $p = shift; my $drawindex = $self->{'drawindex'}; &{$ourDrawFunctions[$drawindex]{'f'}}($p); } # # Called when the print button is clicked. # sub printIt { my $self = shift; my $printer = $self->{'printer'}; if($printer->setup($self)) { my $paint = Qt::Painter->new; $paint->begin($printer); $self->drawIt($paint); $paint->end(); } } sub paintEvent { my $self = shift; my $paint = Qt::Painter->new; $paint->begin($self); $self->drawIt($paint); $paint->end(); } # # Called when the widget has been resized. # Moves the button group to the upper right corner # of the widget. # sub resizeEvent { my $self = shift; my $bgroup = $self->{'bgroup'}; $bgroup->move($self->width()-$bgroup->width(), 0); } package main; use Qt 2.0; import Qt::app; $draw = new DrawView; $app->setMainWidget($draw); $draw->show(); exit $app->exec();