Perl-Programmierung: GTK
Allgemeines zu Gtk2[Bearbeiten]
Mit dem Modul Gtk2 ist es in Perl moeglich, auf Gnome spezialisierte GUIs zu schreiben. Hierzu ist es noetig, dass die Perlbindings fuer die Gtk2-Bibliothek sowie zwei module, Gtk2 und Glib ordentlich auf dem Rechner installiert und konfiguriert sind.
Ein HelloWorld-Programm in Perl/Gtk2[Bearbeiten]
Dieses kleine Beispiel soll deutlich machen, wie man mit Perl/Gtk2 grundlegend umgeht.
#!/usr/bin/perl
use strict;
use warnings;
use Glib;
use Gtk2 '-init';
Der erste Schritt der benoetigt wird ist das einbinden noetigen Module. Die sogenannte Shebangline duerfte inzwischen allgemein bekannt sein, ebenso die Module strict und warnings. Glib stellt grundlegende Funktionen bereit, die vom Gtk2-Modul benoetigt werden. Zum Schluss wird das eigentliche Gtk2-Modul geladen sowie initialisiert.
my $window = Gtk2::Window->new();
my $button = Gtk2::Button->new('Hello World');
In diesem Schritt erschaffen wir jeweils ein Objekt der Klassen Gtk2::Window und Gtk2::Button. Wie die Namen schon vermuten lassen werden wir im fertigen Programm einen Button in einem Fenster haben. Dem Button muss seine Beschriftung direkt im Konstruktor als Parameter mitgegeben werden.
sub schluss
{
Gtk2->main_quit();
exit (0);
}
Diese Subroutine brauchen wir spaeter um das Programm zu schliessen.
$window->add($button);
Mit dieser Methode sorgen wir dafuer, dass der Button dem Fenster zugeordnet wird (er spaeter als content des Fensters auftauchen wird)
$window->signal_connect(destroy => \&schluss);
$button->signal_connect(clicked => \&schluss);
Die Methode signal_connect(event => \&funktion) weisst einem Event eine Funktion zu, die bei dessen auftreten ausgeloest wird. In diesem Beispiel sind das die Events "destroy", das schliessen eines Fensters, und "clicked", ein vollstaendig ausgefuehrter Klick auf einen Button. Beide werden mit der Subroutine "schluss" verknuepft, die das Programm ordnungsgemaess beendet.
$window->show_all();
Diese Methode macht alle in $window vorhandenen Steuerelemente sichtbar.
Gtk2->main();
Die Methode Gtk2->main() startet den Hauptloop der Gtk2-Klasse. Zur Erklaerung: Gtk2 ist ein Eventbasiertes System. Das heisst, es werden in jedem Durchlauf des Mainloops alle auftretenden Events gesammelt und je nachdem, ob sie vorher mit signal_connect einer funktion zugewiesen wurden, werden die Funktionen, auf die sie referieren ausgefuehrt.
Wenn alles richtig gelaufen ist, sollte beim Ausfuehren des Skripts ein Fenster wie Dieses auf ihrem Bildschirm auftauchen, das ueber den Button "Hello World" und ueber das "X" schliessbar ist:
Fensterlayouts[Bearbeiten]
Wenn man ein wenig mit dem HelloWorld-Script herumexperimentiert wird man bald feststellen muessen dass es ohne Weiteres nich moeglich ist, ein zweites steuerelement in das Fenster zu setzen. In Gtk2 kann ein Fenster als Containerelement nur ein einziges Steuerelement aufnehmen. Um dennoch komplexere Fensterlayouts erstellen zu koennen, stellt Gtk2 Boxen zur verfuegung. Das sind Containerelemente, die mehrere Steuerelemente beinhalten koennen. Zudem werden aehnlich wie in Tk Tabellen als Gestaltungselemente angeboten. Wagen wir uns nun an die Erstellung eines Gtk2-Fensters mit 2 Buttons
#!/usr/bin/perl
use strict;
use warnings;
use Glib;
use Gtk2 '-init';
my $window = Gtk2::Window->new();
my $button1 = Gtk2::Button->new('Button 1');
my $button2 = Gtk2::Button->new('Button 2');
my $box = Gtk2::HBox->new();
sub schluss
{
Gtk2->main_quit();
exit (0);
}
$window->signal_connect(destroy=>\&schluss);
$button1->signal_connect(clicked=>\&schluss);
$button2->signal_connect(clicked=>\&schluss);
$box->add($button1);
$box->add($button2);
$window->add($box);
$window->show_all();
Gtk2->main();
Zur Erklaerung des Codes: Wir geben den Interpreterstandort an, binden die noetigen Module ein, erstellen ein Window-Objekt, zwei Button-Objekte und ein HBox-Objekt. Es folgt eine kleine Routine, die das Programm schliesst. Dann weisen wir den Buttons und dem "X" des Fensters diese Routine zu. Danach werden der Box die beiden Buttons zugewiesen und die Box wiederum dem Fenster. Alles wird sichtbar gemacht und das Programm gestartet:
Gtk2 Bietet zwei unterschiedliche Boxen zur Anordnung der Steuerelemente an. Eine VBox und eine HBox. Wie die Bezeichnungen schon vermuten lassen, ordnet die HBox ihre Steuerelemente horizontal an, waehrend die VBox dies vertikal tut. Die Boxen sind und bleiben immer normale Steuerelemente. So kann eine Box einer anderen zugewiesen werden. Mit dieser art von Verschachtelung lassen sich recht Komplexe Oberflaechen erstellen. Testen Sie doch einmal, wie das obige Programm mit einer VBox aussehen wuerde.
Die Methode signal_connect()[Bearbeiten]
Wie wir schon gesehen haben dient die signal_connect()-Methode dazu, eine Routine an ein oder mehrere Events zu binden. sie unterstuetzt aber noch ein weiteres sehr nuetzliches Feature: Die Uebergabe von Daten. Um zu erklaeren wozu das gut sein soll stellen wir uns folgende Situation vor: Sie arbeiten an einem Schachprogramm und muessen eine GUI dafuer entwickeln. Jedes Schachfeld wird repraesentiert durch einen Button. Die einzige Moeglichkeit die wir bis jetzt haetten waere es 64 felder an 64 Methoden, eine fuer jedes Feld zu binden. Mit dem Datenuebergabe-Feature allerdings koennen wir eine einzige Routine schreiben, die die Anfragen aller Buttons entgegennehmen kann.
Die signal_connect()-Methode mit einem Skalar:
$buttonA5->signal_connect(clicked=>\&auswertung,"A5");
$buttonA4->signal_connect(clicked=>\&auswertung,"A4");
Um diese mitgegebenen Informationen auszuwerten muesste die Routine "auswertung" so aussehen:
sub auswertung
{
my $ich = shift; #holt das erste element aus dem uebergabe array (eine referenz auf das button-objekt, dass das event ausgeloest hat
my $information = shift; #holt das zweite element aus dem uebergabe array (die mitgegebene information)
print "Feld A5 wurde angeklickt" if ($information eq "A5");
print "Feld A4 wurde angeklickt" if ($information eq "A4");
}
Fuer unser kleines Beispiel einer Schachoberflaeche bedeutet das, dass eine einzige Methode in der Lage ist alle Klicks auf dem Schachfeld zu analysieren und zu verarbeiten. Eine schoene Methode um seeehr viel Zeit und LoC zu sparen. Natuerlich ist es auch moeglich der Auswertungsroutine eine Variable anstatt einem statischen Wert mitzugeben. Auch Array- oder Hashreferenzen sind kein Hindernis.
Ein- und Ausgabe[Bearbeiten]
Es ist so langsam Zeit sich der eigentlichen Aufgabe der GUI zuzuwenden: Der Aus- und Eingabe. Gtk2 bietet eine Vielzahl an Steuerelementen an, mit denen der User dem Script Eingaben übermitteln kann. Den größten Bekanntheitsgrad hat vermutlich die Textbox, deren Klasse in Gtk2 Gtk2::Entry heißt. Mit der Textbox im Repertoire sind wir in der Lage ein kleines Script zu schreiben, das 2 Strings als Input annimmt, diese kombiniert und auf einem Gtk2::Label wieder ausgibt. Den in einem Gtk2::Entry eingetragenen Text können wir mit der Methode get_text() in eine Variable laden. Andersherum funktioniert das beim Gtk::Label, in das wir den produzierten String schreiben wollen. Die Methode nennt sich hier set_text($beliebiger_string). Umgesetzt müsste dieses Programm so ähnlich aussehen wie hier:
#!/usr/bin/perl
use strict;
use warnings;
use Glib;
use Gtk2 '-init';
my $window = Gtk2::Window->new;
my $button = Gtk2::Button->new('Kombinieren');
my $entry1 = Gtk2::Entry->new();
my $entry2 = Gtk2::Entry->new();
my $output = Gtk2::Label->new();
my $box = Gtk2::VBox->new();
sub schluss
{
Gtk2->main_quit();
exit (0);
}
sub auswertung
{
my $string1 = $entry1->get_text();
my $string2 = $entry2->get_text();
$output->set_text($string1." ".$string2);
}
$window->signal_connect(destroy=>\&schluss);
$button->signal_connect(clicked=>\&auswertung);
$box->add($entry1);
$box->add($entry2);
$box->add($button);
$box->add($output);
$window->add($box);
$window->show_all();
Gtk2->main();
Das Ergebnis sollte in etwa so aussehen:
Versuchen sie doch einmal, ein Script zu schreiben, das 3 Zahlen miteinander addiert! Wie es für Textelemente die Methoden set_text() und get_text() gibt, so gibt es auch für alle anderen Steuerelemente Methoden, über die man den mit dem Steuerelement bestimmten Wert auslesen und in Variablen ablegen kann. Gtk2 hat wie gesagt eine große Auswahl, z.B. Farbwähler, Checkboxen, Listen, e.t.c
Nuetzliche Methoden fuer Fenster[Bearbeiten]
Am Rande moechte ich noch 2 Methoden ansprechen, die ein Fenster recht stark optisch aufwerten koennen. Die erste waere set_border_width($integer), die dem Fenster eine duch $integer bestimmte Randbreite zuteilt. Die zweite ist set_title($stringt), die einen Text in die Titelleiste des Fensters schreibt. Als Beispiel hab ich folgende Zeilen in das Input-Output-Skript eingefuegt:
$window->set_border_width(30);
$window->set_title("Combiner");
Das Ergebnis kann sich sehen lassen:
Links[Bearbeiten]
Hier ist die Complette Table of Contents des Gtk2 Moduls: Saemtliche Methoden, Enumeratoren und Attribute sind hier aufgelistet: Gtk2-Perl Table of Contents