Sziasztok,
hogy mukodik a szubrutin perl/Tk alatt?
Miert fut le a szubrutinban a:
print "$i\n";
resz $i osszes ertekere es csak azutan a grafikai megjelenites:
$st=$mw->Label(-justify => 'left' ,-foreground => "#196f3d" ,-anchor => 's' ,-text => $i)->place(-x=>$dx, -y=>$dy);
Azt szeretnem elerni, hogy kinyomtassa $i erteket es rogton utana
jelenitse meg GUI-ban adott $i erteket.
Ardi
#!/usr/bin/perl
use Tk;
$dx=60;
$dy=0;
my ( $size, $step ) = ( 450, 1);
my $mw = MainWindow->new;
$mw->configure( -width=>$size, -height=>$size );
$mw->geometry('450x350+40+50');
$button = $mw->Button(-text => "Exit", -background => yellow, -foreground => red, -command => sub { exit })->pack(-side => 'left', -anchor => 'n');
$button4 = $mw->Button(-text => "Runx",-background => yellow,-foreground => blue, -command => \&say)->pack(-side => 'left', -anchor => 'n');
sub say{
for (my $i=0; $i <= 3; $i++)
{
print "$i\n";
$st=$mw->Label(-justify => 'left' ,-foreground => "#196f3d" ,-anchor => 's' ,-text => $i)->place(-x=>$dx, -y=>$dy);
sleep(2);
$dy=$dy+20;
}
}
MainLoop;
- 426 megtekintés
Hozzászólások
A Tk egy eseményvezérelt GUI framework, ami azt jelenti, hogy miután bekonfiguráltad a gombjaidat és címkéidet, meghívod a MainLoop függvényt, és ezzel átadod a vezérlést a Tk fő ciklusának, amely vár a bejövő eseményekre (pl. egérmozdulatok, billentyűleütések az ablakban, vagy éppen új címkék létrejötte), és feldolgozza azokat (pl. újrarajzolja az ablakot az aktuális tartalommal).
Ellenben amikor a gomb megnyomására meghívódik a te say nevű callback függvényed, akkor visszaveszed a vezérlést, és nem is adod vissza a kis for ciklusod végéig. Így a Tk-nak nincs esélye reagálni az eseményekre, a GUI be van fagyva, amíg vissza nem kapja a vezérlést a callbacktól.
"Megoldás": kell egy $mw->update a sleep sor elé. Ezzel átmenetileg visszaadod a vezérlést a Tk-nak, hogy dolgozza fel a függőben lévő eseményeket. Ez első közelítésre megoldja a problémádat és a programod azt csinálja, amit szeretnél: az ablakban kb. ugyanakkor jelenik meg a címke, mint a print eredménye a konzolban.
Valójában azonban még mindig hibás a program, a callback-ben használt sleep miatt. A sleep blokkol, addig a 2 másodpercig a programod nem csinál semmit, a GUI eseményeket sem dolgozza fel. Általában az a szabály, hogy eseményvezérelt programban (GUI programban) sleepet vagy más blokkoló műveletet nem szabad használni, mert befagyasztod velük az egész GUI-t.
A helyes megoldás a Tk által adott periodikus időzítő (repeat) használata. Ezzel az eseménykezelőre bízod az ütemezést, a címke hozzáadása a megfelelő időben fog lefutni, miközben a felület végig reszponzív marad.
#!/usr/bin/perl
use strict;
use warnings;
use Tk;
my $dx = 60;
my $dy = 100;
my ($size, $step) = (450, 1);
my $timer;
my $mw = MainWindow->new;
$mw->configure(-width => $size, -height => $size);
$mw->geometry('450x350+40+50');
my $button = $mw->Button(-text => "Exit", -background => 'yellow', -foreground => 'red', -command => sub { exit })->pack(-side => 'left', -anchor => 'n');
my $button4 = $mw->Button(-text => "Runx",-background => 'yellow',-foreground => 'blue', -command => \&start)->pack(-side => 'left', -anchor => 'n');
my $number = 0;
sub start {
add_label();
$timer = $mw->repeat(2000, \&add_label);
}
sub add_label {
print "$number\n";
$mw->Label(-justify => 'left' ,-foreground => "#196f3d" ,-anchor => 's' ,-text => $number)->place(-x=>$dx, -y=>$dy);
$dy=$dy+20;
$number++;
if ($number > 3 and defined $timer) {
$timer->cancel;
undef $timer;
}
}
MainLoop;
- A hozzászóláshoz be kell jelentkezni
Szuper,
ereztem, hogy vmi bibi van a GUI loop-pal.
Bratom is vmi hasonlot ajanlott.
Koszi szepen mindenkinek a segitseget.
Ardi
- A hozzászóláshoz be kell jelentkezni