Zurück |
Übersicht |
Weiter
Kapitel 4 : Ein Knopf löst ein Ereignis aus
Wx::Button
Jetzt haben wir ein Fenster das weitere graphische Bedienelemente (engl. Widgets) aufnehmen kann, wie zum Beispiel Knöpfe (engl. Button). Diese werden mit Wx::Button->new() erzeugt, was auch eine Referenz auf das taufrische Button-Objekt zurückgibt.
Diese Aktion legt aber nur die Optik fest, welche Handlung der Knopf auslöst, wird separat bestimmt. Das scheint bei einfachen Knöpfen wie Bürokraktie, ist aber sinnvoll, weil manche Widgets in Wx über 10 verschiedene Ereignisse (engl. Event kurz EVT) kennen.
Button Event
EVT_BUTTON ist das Ereignis das beim Loslassen eines Knopfes gestartet wird und die Methode EVT_BUTTON erwartet als Parameter jeweils eine Referenz auf das Mutterfenster, den Knopf und die zu startende Routine (coderef), die es miteinander verknüpft. Anstatt einer Coderef hab ich hier direkt die kurze sub { $_[0]->Close(1) } eingefügt, die nur das Fenster schliesst (die 1 hat gleiche Funktion wie bei $frame->show(1)). Statt $_[0] hätte ich dabei auch $frame schreiben können da die sub vom Event als Parameter Referenzen auf das Mutterfenster und auf das Eventobjekt bekommt. Bitte dabei beachten: Ereignismethoden wie EVT_BUTTON werden einzeln aus Wx::Event importiert. Noch eine Falle: bevor ihr Wx wirklich gut kennt, solltet ihr immer den Event vor dem ->Show(1) setzen.
| jim_knopf.pl |
use strict;
use warnings;
ButtonDemo->new->MainLoop;
package ButtonDemo;
use base qw(Wx::App);
use Wx;
use Wx::Event qw( EVT_BUTTON );
sub OnInit {
my $frame = Wx::Frame->new( undef, -1, 'Kapitel 4: Jim stellt sich vor', [-1,-1], [-1, -1]);
my $jim = Wx::Button->new( $frame, 1, ' Drück mich ', [10, 10], [50, 20]);
EVT_BUTTON($frame, $jim, sub {$_[0]->Close(1)});
$frame->Show(1);
}
|
Autosizing
Beim Ausführen des Beispiels ist dir sicher aufgefallen, daß der Knopf die ganze Fläche des Fensters einnimmt, obwohl wir ihm mit [10,10] eine Position gaben und mit [50, 20] eine genaue Größe (50 Pixel breit und 20 Pixel hoch). Da der Knopf auf keinem Panel oder Sizer (nächstes Kapitel) sitzt, sondern auf dem nackten Fenster, nimmt er automatisch die gesamte Fläche ein (wenn er sich den Platz nicht tielen braucht). Würde man einen zweiten Knopf dem Fenster zuweisen, würde er sich an seine Koordinaten halten. Die Größe und Position des Fensters haben wir jeweils mit [-1, -1] auf interne Standardwerte gestellt. Das geht auch mit den Konstanten
wxDefaultSize und
wxDefaultPosition, ich war nur zu bequem die Konstanten vorher anzumelden.
Fang mich!
Gut, aber richtig sinnvoll ist das Beispiel noch nicht, da an jedem Fenster schon ein Knopf zum Schliessen vorhanden ist. Deswegen hab ich daraus ein kleines Spiel gemacht:
| fang_mich.pl |
use strict;
use warnings;
ButtonDemo->new->MainLoop;
package ButtonDemo;
use base qw(Wx::App);
use Wx;
use Wx::Event qw( EVT_BUTTON );
sub OnInit {
my $frame = Wx::Frame->new( undef, -1, 'Kapitel 4: fangt Jim', [-1,-1], [110, 110]);
EVT_BUTTON($frame, Wx::Button->new( $frame, 1, ' Fang mich !'), \&spring_weg);
$frame->Show(1);
}
sub spring_weg {
my $frame = shift;
my $screen = Wx::GetDisplaySize();
my ($x_size, $y_size) = $frame->GetSizeWH();
my $x_pos = int rand $screen->GetWidth - $x_size;
my $y_pos = int rand $screen->GetHeight - $y_size;
$frame->SetSize($x_pos, $y_pos, $x_size, $y_size);
}
|
Mit leichten Änderungen ist hier alles wie oben erklärt, nur die sub spring_weg ist neu. Sie bewegt das Fenster an eine zufällige Position. Dazu wird abgefragt wie groß der sichtbare Bildschrim ist und wie groß das Fenster ist. Das dazu verwendete GetSizeWH ist eine WxPerl eigene Variante, die die Breite(width) und Höhe (height) als Array wiedergibt. Die original Wx Methode GetSize gäbe uns ein Objekt vom Typ WxSize zurück das wir zusätzlich nach den gesuchten Werten befragen müssten.
Zurück |
Übersicht |
Weiter
--
HerbertBreunung - 21 Feb 2006
--
ChristianDuehl - 05 Apr 2006 Rechtschreibung