Perl-Programmierung: GTK


Allgemeines zu Gtk2 Bearbeiten

Mit dem Modul Gtk2 ist es in Perl möglich, auf Gnome spezialisierte GUIs zu schreiben. Hierzu ist es nötig, dass die Perlbindings für 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 benötigt wird ist das einbinden nötigen Module. Die sogenannte Shebangline dürfte inzwischen allgemein bekannt sein, ebenso die Module strict und warnings. Glib stellt grundlegende Funktionen bereit, die vom Gtk2-Modul benötigt 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 später um das Programm zu schließen.

$window->add($button);

Mit dieser Methode sorgen wir dafür, dass der Button dem Fenster zugeordnet wird (er später 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 ausgelöst wird. In diesem Beispiel sind das die Events "destroy", das Schließen eines Fensters, und "clicked", ein vollständig ausgeführter Klick auf einen Button. Beide werden mit der Subroutine "schluss" verknüpft, die das Programm ordnungsgemäß 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 Erklärung: Gtk2 ist ein Event-basiertes 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 ausgeführt.

Wenn alles richtig gelaufen ist, sollte beim Ausführen des Skripts ein Fenster wie dieses auf ihrem Bildschirm auftauchen, das über den Button "Hello World" und über das "X" schliessbar ist:  

Fensterlayouts Bearbeiten

Wenn man ein wenig mit dem HelloWorld-Script herumexperimentiert wird man bald feststellen müssen dass es ohne Weiteres nicht möglich 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 können, stellt Gtk2 Boxen zur Verfügung. Das sind Containerelemente, die mehrere Steuerelemente beinhalten können. Zudem werden ähnlich 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 Erklärung des Codes: Wir geben den Interpreterstandort an, binden die nötigen Module ein, erstellen ein Window-Objekt, zwei Button-Objekte und ein HBox-Objekt. Es folgt eine kleine Routine, die das Programm schließt. 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, während 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 Oberflächen erstellen. Testen Sie doch einmal, wie das obige Programm mit einer VBox aussehen würde.


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 unterstützt aber noch ein weiteres sehr nützliches Feature: Die Übergabe von Daten. Um zu erklären wozu das gut sein soll, stellen wir uns folgende Situation vor: Sie arbeiten an einem Schachprogramm und müssen eine GUI dafuer entwickeln. Jedes Schachfeld wird repräsentiert durch einen Button. Die einzige Möglichkeit, die wir bis jetzt hatten wäre es 64 Felder an 64 Methoden, eine für jedes Feld zu binden. Mit dem Datenübergabe-Feature allerdings können 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, müsste 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");
}

Für unser kleines Beispiel einer Schachoberfläche bedeutet das, dass eine einzige Methode in der Lage ist alle Klicks auf dem Schachfeld zu analysieren und zu verarbeiten. Eine schöne Methode um seeehr viel Zeit und LoC zu sparen. Natürlich ist es auch möglich 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

Nützliche Methoden für Fenster Bearbeiten

Am Rande möchte ich noch 2 Methoden ansprechen, die ein Fenster recht stark optisch aufwerten können. Die erste wäre 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 eingefügt:

$window->set_border_width(30);
$window->set_title("Combiner");

Das Ergebnis kann sich sehen lassen:

 

Links Bearbeiten

Hier ist die komplette Inhalt des Gtk2 Moduls: Sämtliche Methoden, Enumeratoren und Attribute sind hier aufgelistet: Gtk2-Perl Table of Contents