in reply to Updating a Tk Widget from a foreach loop
The problem is that Tk doesn't actually display widgets until the call to MainLoop(), and you've done all your delays and drawing before that even gets called.
One way to do this using a for loop (as you prefer) is to set up a series of 'after' timers just before the call to MainLoop. Also, you do not have to create new rectangle and text items in the canvas just to update, you can create those objects once and then update them (that's what I'll do in this example):
#!/usr/bin/perl -w use strict; use Tk; my $mw = new MainWindow; my $rec1 = $mw->Canvas(-height => "90", -width => "450")->pack(); my $rec_tag = $rec1->createRectangle(1,1,450,90, -fill => "black"); my $txt_tag = $rec1->createText(225,45, -justify => "center", -fill => "yellow", -font => "times 62", ); my @junk = (0,1,2,3,4,5,6,7,8,9); # set up timed updates here: my $delay = 0; foreach my $n (@junk) { $delay += 500; $mw->after($delay,[\&delay_type, $n]); } MainLoop(); sub delay_type { my $n = shift; $rec1->dchars($txt_tag,0); $rec1->insert($txt_tag,0,$n); }
Alternatively, if you weren't necessarily tied to using a for loop, you could use a 'repeat' timer (and cancel it when done). In this example, everything up to the 'set up timed updates' comment is assumed to be the same as above:
# set up timed updates here: my $timer = $mw->repeat(500,\&delay_type); MainLoop(); sub delay_type { $timer->cancel() and return unless @junk; my $n = shift @junk; $rec1->dchars($txt_tag,0); $rec1->insert($txt_tag,0,$n); }
That last example would destroy @junk in the process, so you may want to adjust to use a copy if you need to.
|
|---|