Perl (118) - Tk - čas a události

Perl K bezproblémovému běhu každé aplikace, která má něco smysluplného umět, je potřeba, abychom uměli vyvolávat a zpracovávat události.

15.10.2010 00:00 | Jiří Václavík | přečteno 11449×

Práce s časem

Pro odložené nebo opakované vykonávání nějaké akce máme v Tk zabudované metody after a repeat. Metodou after vytvoříme jednorázový příkaz, který bude vykonán za určený čas. Toto je v jistém smyslu analogie s unixovým nástrojem at.

Podobně funguje metoda repeat, která vytváří trvalý příkaz. Zde se akce periodicky opakuje.

Vyzkoušíme si to a napíšeme si jednoduchou hru. Ta bude spočívat v tom, že uživatel musí co nejdéle bez přestávky klikat na tlačítko. Jakmile jednou nestihne kliknout včas, hra skončí a oznámíme mu, kolikkrát se mu podařilo kliknout. V programu využijeme ještě metodu cancel, která jednorázový příkaz ruší.

use Tk;
use strict;

my $m = MainWindow->new();
my $pocetkliku = 0;
my $casovac;

$m->Label(-text=>"Ukolem hry je klikat na tlacitko co nejdele.")->pack();
$m->Button(-text=>"Aktivita!", -command=>\&klik)->pack();
$m->Button(-text=>"Konec", -command=>sub{exit})->pack();

MainLoop();

sub klik {
  $pocetkliku++;
  $casovac->cancel if $pocetkliku!=1;
  $casovac=$m->after(200, \&konec);
}

sub konec {
  $m->messageBox(-message => "Klikl jsi ${pocetkliku}krat.", -type => "ok");
  $pocetkliku = 0;
}

Události

S některými událostmi jsme se setkali již dříve. Šlo například o stisk tlačítka. Teorii událostí nyní podstatně rozvineme.

S událostmi lze manipulovat pomocí metody bind, kterou lze volat nad libovolným widgetem. Předáváme jí typ události a akci, která se má vykonat. Metoda bind nám umožňuje zachytávat takové události jako je například stisky a uvolnění kláves nebo tlačítek na myši, pohyb kurzorem myši.

Zápis událostí

Událost se zapisuje jako nějaký řetězec uzavřený mezi symboly <>. Přesněji řečeno má každá událost následující tvar.

<klávesa1-klávesa2-...-klávesan-typ-symbolické_jméno_klávesy>

Přitom klávesy můžeme dosadit například pro události z myši Button1, Button2, Double, Triple a pro události z klávesnice Control, Alt, Shift. Any zastupuje libovolnou klávesu.

Typ události nabývá jedné z následujících hodnot:

Poslední položka, symbolické_jméno_klávesy, nabývá obvykle pro tisknutelné znaky tohoto znaku. Pro jiné klávesy existují speciální řetězce jako například Enter, BackSpace, F7 apod. Kompletní seznam možností je na tcl.activestate.com/man/tcl8.4/TkCmd/keysyms.htm.

Často používané události lze různými způsoby zkracovat zkracovat, takže můžeme vynechávat KeyPress a ButtonPress. Uveďme několik příkladů zápisu události.

Již bylo řečeno, že příkaz bind sváže událost a akci. bind přijímá jako parametr buď událost nebo posloupnost událostí. Posloupnost se zapisuje jako několik událostí oddělených mezerou.

Zjištění přesné příčiny události

Již jsme zmínili, že událost <Any-KeyPress> znamená stisk libovolné klávesy. Otázkou však je, jak potom zjistíme, která klávesa vlastně byla stisknuta. Řešení nalezneme ve volání funkce Ev, která nám je schopna poskytnout libovolnou informaci o nastálé události. Tato funkce přijímá parametr ve formě řetězce, podle kterého vrací požadovanou informaci. Možné parametry jsou například následující.

parametrVýznam
xx-souřadnice myši
yy-souřadnice myši
knázev klávesy
tčas události
use Tk;

$m = MainWindow->new;
$m->configure(-width=>400, -height=>400);

$p = $m->Canvas(-cursor=>"crosshair", -width=>400, -height=>400, -background=>"white")->pack;

for($i=10; $i<200; $i+=10){
  $h=255/400*$i;
  $p->createRectangle($i, $i, 400-$i, 400-$i, -outline=>sprintf("#%02x%02x%02x", $h, $h, $h));
}
$status=$m->Label(-text=>"Klikni nekam do okna.")->pack();

$p->Tk::bind( "<Button-1>", [sub{$status->configure(
  -text=>"Klikl jsi na pozici [$_[1], $_[2]]")}, Ev("x"), Ev("y")]);
MainLoop;

Zajímavý je pro nás předposlední řádek. Jakmile klikneme levým tlačítkem někam do okna, vyvolá se událost <Button-1>. Protože jsme pomocí bind vytvořili k této události vazbu, dojde k provedení příslušné akce. Připomeňme, že, chceme-li akci předat parametry, musíme je vložit společně s odkazem na podprogram do pole.

Předchozí program vytvoří následující okno.

Zachycení události (kliknutí do prostoru okna) a výpis souřadnic kurzoru myši

Vyvolání více událostí zároveň

Podívejme se nyní na situaci, kdy uživatel vykonal dvojité kliknutí myši. Nastaly dvě události: <Button-1> a <Double-Button-1>. V takovém případě má přednost méně obecná událost, tedy v našem případě <Double-Button1>. To znamená, že po prvním kliknutí je okamžitě vyvolána událost <Button-1> a po druhém kliknutí už pouze <Double-Button-1>.

Online verze článku: http://www.linuxsoft.cz/article.php?id_article=1727