package AnalogClock;
use Qt;
use Qt::isa qw(Qt::Widget);
use Qt::slots
setTime => ['const QTime&'],
drawClock => ['QPainter*'],
timeout => [];
use Qt::attributes qw(
clickPos
_time
);
#
# Constructs an analog clock widget that uses an internal QTimer
#
sub NEW {
shift->SUPER::NEW(@_);
_time = Qt::Time::currentTime(); # get current time
my $internalTimer = Qt::Timer(this); # create internal timer
this->connect($internalTimer, SIGNAL('timeout()'), SLOT('timeout()'));
$internalTimer->start(5000); # emit signal every 5 seconds
}
sub mousePressEvent {
my $e = shift;
if(isTopLevel()) {
# Lack of operators is really noticable here
my $topLeft = Qt::Point(
geometry()->topLeft->x - frameGeometry()->topLeft->x,
geometry()->topLeft->y - frameGeometry()->topLeft->y
);
clickPos = Qt::Point($e->pos->x + $topLeft->x,
$e->pos->y + $topLeft->y);
}
}
sub mouseMoveEvent {
my $e = shift;
if(isTopLevel()) {
move(Qt::Point($e->globalPos->x - clickPos->x,
$e->globalPos->y - clickPos->y));
}
}
sub setTime {
my $t = shift;
timeout();
}
#
# The QTimer::timeout() signal is received by this slot.
#
sub timeout {
my $new_time = Qt::Time::currentTime(); # get the current time
_time = _time->addSecs(5);
if($new_time->minute != _time->minute) { # minute has changed
if(autoMask()) {
updateMask();
} else {
update();
}
}
}
sub paintEvent {
return if autoMask();
my $paint = Qt::Painter(this);
$paint->setBrush(colorGroup()->foreground);
drawClock($paint);
}
# If clock is transparent, we use updateMask()
# instead of paintEvent()
sub updateMask { # paint clock mask
my $bm = Qt::Bitmap(size());
$bm->fill(&color0); # transparent
my $paint = Qt::Painter;
$paint->begin($bm, this);
$paint->setBrush(&color1); # use non-transparent color
$paint->setPen(&color1);
drawClock($paint);
$paint->end;
setMask($bm);
}
#
# The clock is painted using a 1000x1000 square coordinate system, in
# the centered square, as big as possible. The painter's pen and
# brush colors are used.
#
sub drawClock {
my $paint = shift;
$paint->save;
$paint->setWindow(-500,-500, 1000,1000);
my $v = $paint->viewport;
my $d = min($v->width, $v->height);
$paint->setViewport($v->left + ($v->width-$d)/2,
$v->top - ($v->height-$d)/2, $d, $d);
# _time = Qt::Time::currentTime();
my $pts = Qt::PointArray();
$paint->save;
$paint->rotate(30*(_time->hour%12-3) + _time->minute/2);
$pts->setPoints([-20,0, 0,-20, 300,0, 0,20]);
$paint->drawConvexPolygon($pts);
$paint->restore;
$paint->save;
$paint->rotate((_time->minute-15)*6);
$pts->setPoints([-10,0, 0,-10, 400,0, 0,10]);
$paint->drawConvexPolygon($pts);
$paint->restore;
for(1 .. 12) {
$paint->drawLine(440,0, 460,0);
$paint->rotate(30);
}
$paint->restore;
}
sub setAutoMask {
my $b = shift;
setBackgroundMode($b ? &PaletteForeground : &PaletteBackground);
Qt::Widget::setAutoMask($b);
}
1;
|
The use of a camel image
with the topic of Perl is a trademark of
O'Reilly & Associates, Inc. Used with
permission.
The Qt logo (TM) is a registered trademark of Trolltech (TM) AS,
Norway.