in reply to algorithm help -- how to label a clock

A canvas widget comes to mind. Here is a start for you, all you need to add is your labels for the text time around the circle. It uses a hack to do a $mw->update inside a for(;;) loop, which should be improved; but it lays out the circular math for you to derive your text_time positions.

A second example below, shows how to do vertical text in case you desire that feature.

#!/usr/bin/perl use warnings; use strict; use Tk; my $pi = atan2(1,1)*4.0; # an amusing transcendental number my $main = MainWindow -> new(); # the primal widget my ($width, $height ); # canvas geometry $width = $height = 500; # change me if you don't like me my $x = int($width/2); my $y = int($height/2); my $r = int($x*0.8) >= int($y*0.8) ? int($x*0.8) : int($y*0.8); # $ra +dius my $c = $main -> Canvas('-width' => $width, '-height' => $height); $c -> create('oval', $x-$r, $y-$r, $x+$r, $y+$r, -width => 2); $c -> pack(-expand => 1, -fill => 'both'); # the following two together _prevent_ resizing: $main -> maxsize($width,$height); # fixes size $main -> minsize($width,$height); # fixes size my ($outickx, $outicky, $intickx, $inticky, $tickwidth); for (0..11) { # the tick initialization loop $outickx = int($x + sin($_*$pi/6.0)*$r*1.00); $outicky = int($y - cos($_*$pi/6.0)*$r*1.00); $intickx = int($x + sin($_*$pi/6.0)*$r*0.85); $inticky = int($y - cos($_*$pi/6.0)*$r*0.85); $tickwidth = $_ % 3 == 0 ? 3 : 1; $c->create('line', ($outickx, $outicky, $intickx, $inticky), -width => $tickwidth, ); } # end tick loop undef $outickx; undef $outicky; # cleanup undef $intickx; undef $inticky; undef $tickwidth; # time and date variables: my ($second,$minute,$hour,$date,$month,$year,$weekday,$yday,$dst); my ($hourx, $houry, $minutex, $minutey ); # clock hand geometry # my ($secondx, $secondy ); # (unused) clock hand geomet +ry for (;;) { # this is the timekeeping lo +op # feel free to make use of some of these variables: ($second,$minute,$hour,$date,$month,$year,$weekday,$yday,$dst) = localtime(); $hour = $hour % 12; ($hourx, $houry, $minutex, $minutey, # $secondx, $secondy, ) = ( int($x + sin((($hour+$minute/60.0)/6.0)*$pi) *$r*0.75 ), int($y - cos((($hour+$minute/60.0)/6.0)*$pi) *$r*0.75 ), int($x + sin( ($minute/30.0)*$pi) *$r*1.00 ), int($y - cos( ($minute/30.0)*$pi) *$r*1.00 ), # int($x + sin( ($second/30.0)*$pi) *$r ), # int($y - cos( ($second/30.0)*$pi) *$r ), ); $c -> delete('hourhand'); $c -> create('line', ($hourx, $houry, $x, $y), '-arrow' => 'first', '-tags' => 'hourhand', '-width' => 3, ); $c -> delete('minutehand'); $c -> create('line', ($minutex, $minutey, $x, $y), '-arrow' => 'first', '-tags' => 'minutehand', '-width' => 2, ); # $c -> delete('secondhand'); # $c -> create('line', ($secondx, $secondy, $x, $y), # '-tags' => 'secondhand', # ); # DoOneEvent; # <- use either this or $main -> update; # <- this (both not necessary). sleep(1); # 1 sec compromise min cpu vs. lively-X } # end timekeeping loop __END__ =head1 NAME pclock =head1 SYNOPSIS pclock & =head1 DESCRIPTION B<pclock> is a clock implemented in Perl/Tk. Here is the `date` on which this was written: Thu May 9 16:58:31 EDT 1996 It was then modified on: Fri May 10 16:31:10 EDT 1996 Thanks to Adrian Phillips and Simon Galton for helpful suggestions. The choice between DoOneEvent; and $main->update; as well as sleep(); times may be system|X-server dependent. As distributed by the author there is a second hand embedded within commented code in this program. =head1 REQUIREMENTS Perl with the Tk extension. =head1 AUTHOR Peter Prymmer pvhp@lns62.lns.cornell.edu =cut
Vertical text example
#!/usr/bin/perl use Tk; my $mw = new MainWindow; my $c = $mw->Canvas->pack; $c->createText(50, 50, -text => 'Hello', -width => 1, ); MainLoop;

I'm not really a human, but I play one on earth.
Old Perl Programmer Haiku ................... flash japh

Replies are listed 'Best First'.
Re^2: algorithm help -- how to label a clock
by Anonymous Monk on Jun 17, 2011 at 12:43 UTC
    Here is mine Tk::Zinc version, with a little help from Advantages of Tk::Zinc over plain Canvas, Tk::Clock, -tk Moving circle, it works, but rotate is busted :)
    #!/usr/bin/perl -- use warnings; use strict; use Tk; use Tk::Zinc ; use Tk::Clock; my $mw = tkinit; my $canvas = $mw->Zinc( -width => 300, -height => 300, -backcolor => 'white', )->pack(qw/ -expand 1 -fill both -padx 10 -pady 10 /); my $clock = $mw->Clock( useAnalog => 1, )->pack; my $circle_radius = 100; my $origin_x = $canvas->cget('-height') / 2 ; my $origin_y = $canvas->cget('-width') / 2; my $cgroup = $canvas->add('group',1,-visible=> 1); #~ my $circle = $canvas->createOval( my $innercircle = $canvas->add( 'arc', $cgroup, [ $origin_x - ( $circle_radius - 10 ), $origin_y - ( $circle_radius - 10 ), $origin_x + ( $circle_radius - 10 ), $origin_y + ( $circle_radius - 10 ), ], ); my $circle = $canvas->add( 'arc', $cgroup, [ $origin_x - $circle_radius, $origin_y - $circle_radius, $origin_x + $circle_radius, $origin_y + $circle_radius, ], ); my $ix=0; my $PI=3.141592635; my $angle = -30; for my $dtick ( 1 .. 12 ){ my $d8 = 9; $angle += 30; my $cos = cos($angle*$PI/180); my $sin = sin($angle*$PI/180); my $x1 = $origin_x + ( ( $circle_radius - $d8 ) * $sin ); my $y1 = $origin_y - ( ( $circle_radius - $d8 ) * $cos ); my $x2 = $origin_x + ( ( $circle_radius + $d8 ) * $sin ); my $y2 = $origin_y - ( ( $circle_radius + $d8 ) * $cos ); #~ my $line = $canvas->createLine ( my $line = $canvas->add( 'curve', $cgroup, [ $x1, $y1, $x2, $y2, ], -tags => "tick", -linecolor => 'red', -filled => 1, -linewidth => 1.0, ); my $text = $canvas->add( 'text', $cgroup, -position => [ $x1,$y1 ], -text => ixHour( $ix++) , -color => 'blue', ); # no work, disappeared or crash #~ $canvas->rotate( $text, $angle , 'degree' ); } MainLoop; sub ixHour { return [qw/ one two three four five six seven eight nine ten eleven twelve /]->[ -1 + shift ] } __END__