Notizen
Bildschirmpräsentation
Gliederung
1
Perl / Tk
  • Einführung in die Erstellung
  • grafischer Oberflächen
  • mit Perl / Tk


  • von Christian Dühl
2
Woraus bestehen grafische Oberflächen?
  • Grafische Oberflächen bestehen aus verschiedenen Fenster-Elementen, sogenannten Widgets, die zur Information des Anwenders oder zur Interaktion mit dem Anwender dienen.


  • Diese Widgets reichen von der Anzeige eines einfachen Wortes bis zu Textfeldern, die schon viele Eigenschaften eines Editors aufweisen und zu mächtigen vektororientierten Zeichenflächen.
3
Verschiedene Widgets an einem Beispiel
  • Rechts sieht man das Optionenmenü von Powerpoint, folgende Widgets lassen sich erkennen:
  •  Texteingabefelder (Entrys)
  •  Überschriften (Label)
  •  Auswahlfelder (Checkboxen)
  •  Rahmen (Frames)
  •  Schalter (Buttons)
  •  Reiter (NoteBooks)
4
Grundsätzliches zur Programmierung grafischer Oberflächen
  • Bei grafischen Oberflächen hat das Programm keine lineare Handlungssteuerung, wie man es von der „normalen“ Programmierung her gewohnt ist. Das liegt daran, dass man dem Benutzer nicht die Reihenfolge seiner Eingaben vorgeben möchte. Der Benutzer muss etwa im Dialog auf der vorigen Folie nicht von oben nach unten seine Wünsche eingeben, sondern kann auf ein beliebiges Widget klicken bzw. Text in beliebige Eingabefelder eintragen.
  • Diese Aktionen des Benuztzers nennt man Ereignisse („Events“) und der Programmablauf ist nun ereignisgesteuert, das heißt, dass das Programm auf bestimmte Ereignisse reagiert. Um dies tun zu können, gibt es eine Schleife, die immer wieder durchlaufen wird, und in der auftretende Ereignisse (vom Benutzer oder anders ausgelöst) behandelt werden.
  • Diese Ereignisschleife wird von Perl/Tk bereitgestellt und kann mit dem Befehl MainLoop()aufgerufen werden.
5
"Während solche Funktionen ablaufen"
  • Während solche Funktionen ablaufen, reagiert die Oberfläche nicht auf Benutzereingaben. Normalerweise ist dies nicht schlimm, wenn nach dem Druck auf etwa den Ok-Button kurz etwas gemacht wird und der Dialog dann beispielsweise verschwindet.


  • Sollte man längere Berechnungen durchführen, so kann man dies der Oberfläche vorher mitteilen (dafür gibt es die Methoden Busy und Unbusy). Dann wird unter anderem ein Wartecursor angezeigt.


  • Sehr lange Wartezeiten sollte man dann mit einem Fortschrittsbalken oder ähnlichem „unterhaltsam“ gestalten.


  • Nun kommen wir zum ersten Perl/Tk-Programm.
6
Hallo Welt
  • #!/usr/bin/perl
  • use strict;
  • use warnings;


  • use Tk;


  • my $mw = MainWindow->new();


  • $mw->Label(-text => 'Hallo Welt')
  •     ->pack();


  • MainLoop();
7
Besprechung zu Hallo Welt
  • Wenn man mal die „Vorrede“ (Shebang, Pragmas und use Tk;) und den Aufruf der MainLoop weglässt, bleiben nur zwei Anweisungen übrig.
  •     my $mw = MainWindow->new();
  • Damit wird ein neues Objekt vom Typ MainWindow erzeugt. Mindestens ein solches Objekt wird in jedem Perl/Tk-Programm gebraucht. Mit
  •     $mw->Label(-text => 'Hallo Welt')
            ->pack();
  • wird eine Überschrift (Label) erzeugt, die den Text „Hallo Welt“ anzeigt. Genauer gesagt wird ein Label-Objekt erzeugt. Hinterher wird noch die Methode pack des erzeugten Objektes aufgerufen. Dann wird das Objekt wieder vergessen. Man könnte es mit „my $label =“ vorweg „einfangen“, aber es wird hier nicht weiter benötigt.
  • Die Methode pack() packt ein Widget ins erzeugende Fenster (oder Rahmen),  hier ins Hauptfenster. Dabei kann man nähere Angaben machen, wie das Objekt eingefügt werden soll. Die Darstellung hängt sehr davon ab, in welcher Reihenfolge die Objekte gepackt werden.
8
Geometrie-Manager
  • pack: Der Standardgeometriemanager, man umgibt Gruppen von Widgets mit (meist unsichtbaren) Rahmen, um diese gemeinsam anzuordnen.
  • grid: Ein Geometriemanager für tabellenartige Fenster.
  • place: Ein Geometriemanager zur freien Platzierung von Widgets. Mit diesem Manager können Widgets auch überlappt dargestellt werden.
9
Das Schalter Widget
  • #!/usr/bin/perl
  • use strict;
  • use warnings;
  • use Tk;


  • my $mw = MainWindow->new();


  • $mw->Button(-text    => 'Klick mich',
  •             -command => sub { $mw->destroy() },
  •            )
  •      ->pack();


  • MainLoop();
10
Besprechung zum Schalter Widget
  • Mit den Zeilen


  •     $mw->Button(-text    => 'Klick mich',
                    -command => sub { $mw->destroy() },
                   )
             ->pack();


  • wird ein Schalter-Objekt (Button) erzeugt und gepackt. Der Schalter bekommt die Aufschrift „Klick mich“ und außerdem wird über -command eine sogenannte Callback-Funktion hinterlegt, die aufgerufen wird, wenn der Schalter ausgelöst wird.
  • Im Beispiel ist die Callback-Funktion eine Closure, man könnte statt sub {...} auch eine Referenz zu einer benannten Funktion angeben, etwa so:


  •         -command => \&beenden


  • Wieder könnte man das Schalter-Objekt mit „my $schalter =“ vor der obigen Zeile für die spätere Verwendung abspeichern, aber das ist hier noch nicht nötig.
11
Widget-Optionen
  • -option => Anweisung  ist typischer Tk-Stil um Parameter festzulegen. Hier ein paar Widget-Optionen, die man häufiger anwendet:


  • Widget-Option mögliche Werte Bedeutung
  • -anchor "n", "ne", "e", "se", "s", "sw", "w", Der Text wird an dieser Position verankert. "nw" oder "center "
  • -background Farbe (etwa 'SeaGreen3') Legt die Hintergrundfarbe des Widgets fest.
  • -borderwidth Betrag Ändert die Breite des Rahmens.
  • -command Callback (Funktionsreferenz, anonyme Subroutine Aktiviert die Callback-Funktion, wenn das
    oder anonyme Liste, deren erstes Element Widget angeklickt wird.
    eine Funktionsreferenz und deren weitere Elemente
    Parameter für diese Funktion sind):
        \&myfunc
        sub { ... }
        [ \&myfunc, $arg1, $arg2, \@arg3 ]
  • -height Betrag (in Pixeln oder Zeilen) Ändert die Höhe des Widgets.
  • -width Betrag (in Pixeln oder Zeichen) Ändert die Breite des Widgets.
  • -justify "left", "right" oder "center“ Ausrichtung von mehrzeiligen Text.
  • -relief "flat", "groove", "raised", "ridge", Ändert den Kantentyp.
    "sunken" oder "solid "
  • -state "normal", "disabled" oder "active " Der Status des Widgets.
  • -text "Text " Der Textstring, der im Widget angezeigt wird.
  • -textvariable Variablenreferenz: \$text Wie -text , nur das sich der Text ändert,
    wenn die Variable $text sich ändert.
  • -title "Titel" Gibt dem Widget einen Titel.
12
Das Eingabefeld Widget
  • #!/usr/bin/perl
  • use strict;
  • use warnings;
  • use Tk;


  • my $mw = MainWindow->new();


  • $mw->Entry()->pack();


  • MainLoop();
13
Besprechung zum Eingabefeld Widget
  • Mit der Zeile


  •     $mw->Entry()->pack();


  • wird ein Eingabefeld-Objekt (Entry) erzeugt und gepackt. In diesem Eingabefeld können einzeilige Eingaben des Benutzers entgegengenommen werden.
  • Man kann es auch beim Start des Programms schon mit Text vorbelegen, den der Benutzer dann ggf. ändern kann.


  • Möchte man später abfragen, was der Benutzer in das Eingabefeld eingetragen hat, so kann man dazu die Methode get verwenden. Dazu muss man das Eingabefeld bei der Erzeugung aber in einer Variablen abspeichern:
        my $entry = $mw->Entry()->pack();
    Dann kann man den Inhalt mit
        my $input = $entry->get();
    ermitteln.
  • Alternativ kann man beim Erzeugen des Eingabefeldes mit
        -textvariable => \$text
    eine (vorher definierte) Variable an das Eingabeelement binden. Ändert man den Inhalt der Variablen, so ändert sich der angezeigte Text und umgekehrt.
14
Rahmenelement und Skalen Widget
  • #!/usr/bin/perl
  • use strict;
  • use warnings;
  • use Tk;
  • my $mw = MainWindow->new();


  • my $f1 = $mw->Frame(-relief      => 'sunken',
  •                     -width       => '50',
  •                     -height      => '50',
  •                     -borderwidth => '1',
  •                    )
  •              ->pack();


  • $f1->Scale(-from   => 0,
  •            -to     => 100,
  •            -orient => "vertical",
  •            -label  => "Schieb mich",
  •           )
  •     ->pack();


  • MainLoop();
15
Besprechung zum Rahmenelement
  • Mit den Zeilen


  •     my $f1 = $mw->Frame(-relief      => 'sunken',
  •                         -width       => '50',
  •                         -height      => '50',
  •                         -borderwidth => '1',
  •                        )
  •                  ->pack();


  • wird ein Rahmenelement (Frame) $f1 mit den Maßen 50x50 Pixeln und der Randbreite 1  Pixel erzeugt und in das Hauptfenster $wm gepackt.


  • Es hat die Reliefart „sunken“. Außerdem gibt es noch die Reliefarten raised, flat, ridge, solid und groove (vergleiche perldoc Tk::options). Diese Reliefarten kann man auch bei anderen Widgets setzen, die Defaultwerte der Reliefart sind von Widget zu Widget unterschiedlich.
16
Besprechung zum Skalen Widget
  • Mit den Zeilen
  •     $f1->Scale(-from   => 0,
                   -to     => 100,
                   -orient => "vertical",
                   -label  => "Schieb mich",
                  )
            ->pack();
  • wird ein Skalenelement erzeugt und in den Rahmen $f1 gepackt. Das Skalenelement hat den Wertebereich von 0 bis 100, ist vertikal ausgerichtet und trägt das Label „Schieb mich“.


  • Nun kommen wir zu einem etwas komplexeren Programm, an dem einige weitere Widgets und das generelle Umgehen mit und das Auslesen von Widgets erläutert wird.
17
Auswahlmöglichkeiten: Radiobutton, Checkbox und Listbox
18
 
19
 
20
 
21
 
22
 
23
Besprechung zu Radiobutton, Checkbox und Listbox
  • Und so sieht das Programm dann aus. Der Benutzer kann mit Checkbuttons (jeder einzelne wählbar oder nicht wählbar), Radiobuttons (nur eine Auswahl pro Gruppe) und der Listbox (hier: mehrere Einträge gleichzeitig auswählbar) seine „Bestellung“ zusammenklicken und dann per OK-Button absenden.
24
"Sahne"
  • Sahne      : ja
    Extrawaffel: ja
    Streusel   : Zartbitterabrieb
    Sauce      : Schokoladensauce
    Vanille
    Schokolade
    Malaga
    Wallnuss
    weiße Schokolade


  • Aber natürlich könnte hier auch etwas anderes passieren, etwa die Bestellung per E-Mail an den nächsten Eisladen zu verschicken oder dergleichen.
25
Besprechung zum Geometriemanager pack
  • Hier tauchten nun zum ersten Mal Optionen der Methode pack auf. Etwa beim Schalter:


  •     pack(-side   => 'bottom',
  •          -expand => 0,
  •          -fill   => 'none',
  •          -ipadx  => 20,
  •          -pady   => 2,
  •         );


  • pack-Option mögliche Werte Bedeutung
  • -side "left", "right", "top" oder "bottom" Platziert das Widgetrechteck an die angegebene Seite
    des Fensters oder Frames.
  • -fill "none", "x", "y" oder "both" Das Widgetrechteck breitet sich in die angegebene
    Richtung aus.
  • -expand 1 oder 0 Das Widget füllt den Platz im Widgetrechteck aus
    (oder nicht).
  • -ipadx Betrag in Pixeln Definiert einen horizontalen Abstand um das Widget
  • (dabei wird es um 2xBetrag in horizontaler Richtung
    vergrößert).
  • -ipady Betrag in Pixeln Definiert einen vertikalen Abstand um das Widget
    (dabei wird es um 2xBetrag in vertikaler Richtung
    vergrößert).
  • -padx Betrag Setzt links und rechts je Betrag Pixel Polster ein.
  • -pady Betrag Setzt oben und unten je Betrag Pixel Polster ein.
  • -anchor "n", "ne", "e", "se", "s", "sw", "w", "nw“ Verankert das Widget in seinem Rechteck an der
    oder "center“ angegebenen Stelle.
26
Rollbalken Widget
  • #!/usr/bin/perl
  • use strict;
  • use warnings;
  • use Tk;
  • my $mw  = MainWindow->new();


  • my $box = $mw->Scrolled('Listbox',
  •                         -scrollbars => 'oe',
  •                         -height     => 5,
  •                        )
  •                  ->pack(-side       => 'left',
  •                         -fill       => 'both',
  •                         -expand     => 1,
  •                        );


  • $box->insert('end', $_)
  •     for qw(Eins Zwei Drei Vier Fünf Sechs Sieben Acht Neun Zehn);


  • MainLoop();
27
Besprechung zum Rollbalken Widget
  • Mit den Zeilen
  •     my $box = $mw->Scrolled('Listbox',
                                -scrollbars => 'oe',
                                -height     => 5,
                               )
  • wird eine Listbox erzeugt, die über einen optionalen „östlichen“ Rollbalken (Scrollbar) verfügt und fünf Zeilen hoch ist. Mit
  •     $box->insert('end', $_)
            for qw(Eins Zwei Drei Vier Fünf Sechs
                   Sieben Acht Neun Zehn);
  • werden nacheinander ans Ende der Listbox zehn Werte eingefügt. Da die Listbox nur fünf Zeilen hoch ist, wird der Rollbalken benötigt (und deshalb angezeigt).
28
Zeichenflächenelement
  • #!/usr/bin/perl
  • use strict;
  • use warnings;
  • use Tk;
  • my $mw = MainWindow->new();


  • my $c1 = $mw->Canvas(-width  => '350',
  •                      -height => '350',
  •                     )
  •               ->pack();


  • $c1->createLine( 25, 175, 325, 175,
  •                 -arrow => 'last', );
  • $c1->createText( 335, 175,
  •                 -fill  => 'blue',
  •                 -text  => 'X', );
  • $c1->createLine(175, 325, 175,  25,
  •                 -arrow => 'last', );
  • $c1->createText(175,  15,
  •                 -fill  => 'darkgreen',
  •                 -text => 'Y',
  •                );


  • MainLoop();
29
Besprechung zum Zeichenflächenelement
  • Mit den Zeilen


  •     my $c1 = $mw->Canvas(-width  => '350',
                             -height => '350',
                            )


  • wird eine Canvas erzeugt, welche 350x350 Pixel groß ist. Dann werden mit createLine und createText x-, y-Achse und Achsenbeschriftungen erzeugt:


  •     $c1->createLine( 25, 175, 325, 175,
                        -arrow => 'last', );
        $c1->createText( 335, 175,
                        -fill  => 'blue',
                        -text  => 'X', );
30
Text-Element
  • #!/usr/bin/perl
  • use strict;
  • use warnings;
  • use Tk;
  • my $mw = MainWindow->new();


  • $mw->Button(-text    => 'Exit',
  •             -command => [$mw => 'destroy'],
  •            )
  •      ->pack(-side    => 'bottom');


  • $mw->Scrolled('Text',
  •               -scrollbars => 'osoe',
  •               -wrap       => 'none',
  •              )
  •        ->pack(-expand     => 1,
  •               -fill       => 'both',
  •              );


  • MainLoop();
31
Besprechung zum Text-Element
  • Mit den Zeilen
  •     $mw->Scrolled('Text',
                      -scrollbars => 'osoe',
                      -wrap       => 'none',
                     )
  • wird ein Textelement erzeugt, welches rechts und unten über optionale Scrollbalken verfügt. Der Text wird nicht umgebrochen.
  • Der Exit-Button wird zuerst eingesetzt, damit er auch noch zu sehen ist, wenn das Fenster stark verkleinert wird. Damit er trotzdem unter dem Text-Widget landet, wird er mit
        -side => 'bottom'
    gepackt.
32
Reiterelement
  • #!/usr/bin/perl
  • use strict;
  • use warnings;
  • use Tk;
  • use Tk::NoteBook;
  • my $mw = new MainWindow;


  • my $nb = $mw->NoteBook()->pack();


  • my $page1 = $nb->add('PageID-1',
  •                      -label => 'Reiter Eins', );
  • my $page2 = $nb->add('PageID-2',
  •                      -label => 'Reiter Zwei', );


  • $page1->Label(-text => 'In Seite 1')->pack();
  • $page2->Label(-text => 'In Seite 2')->pack();


  • MainLoop();
33
Besprechung zum Reiterelement
  • Mit den Zeile
  •     my $nb = $mw->NoteBook()->pack();
  • wird ein Reiterelement (NoteBook) erzeugt und gepackt. In diesem werden nun mit
  •     my $page1 = $nb->add('PageID-1',
                             -label => 'Reiter Eins', );
        my $page2 = $nb->add('PageID-2',
                             -label => 'Reiter Zwei', );
  • zwei Seiten angelegt mit den Reitertiteln „Reiter Eins“ und „Reiter zwei“. In die Seiten wird nun noch je ein Label gesetzt:
  •     $page1->Label(-text => 'In Seite 1')->pack();
        $page2->Label(-text => 'In Seite 2')->pack();
34
Menüsystem
  • Man kann seinem Perl/Tk-Programm ein Menü hinzuzufügen, das man wie man es unter Windows gewöhnt ist, mit Alt+Buchstabe aufrufen und mit Maus und Tastatur darin navigieren kann. Einzelnen Menüpunkten kann man dabei Tastenkürzel zuordnen, die auch im Menü angezeigt werden.


  • Das Beispielprogramm menu.pl ist ziemlich lang, deshalb gehe ich zunächst auf den wichtigen Punkt, das Menü ein.
  • Das gesamte Programm kopiere ich unkommentiert auf eine ausgeblendete Folie für alle, die sich diesen Vortrag selbst ansehen.
35
Erstellen eines Menüsystems:
  • 1.) Menü (Menubar) erstellen:
        my $menu = $mw->Menu(-type => 'menubar');


  • 2.) Dem Fensterwidget dieses Menü zuweisen:
        $mw->configure(-menu => $menu);


  • 3.) Eigentliche Menüs in der Menubar eintragen:
        $menu->cascade(-label     => 'Datei',
                       -underline => 0,              );
        $menu->cascade(-label     => 'Bearbeiten',
                       -underline => 0,              );
        $menu->separator();
        $menu->cascade(-label     => 'Hilfe',
                       -underline => 0,              );


36
4.) Die einzelnen Untermenüs definieren:
    my $menu_datei = $menu
        ->Menu(-menuitems => [
                              [
                               'command'    => 'Datei neu',
                               -command     => \&datei_neu,
                               -accelerator => 'Ctrl-N',
                               -underline   => 6,
                              ],
                              ..........
                              '-',
                              [
                               'command'    => 'Beenden',
                               -command     => \&tk_ende,
                               -accelerator => 'Ctrl-B',
                               -underline   => 0,
                              ],
                            ],
              );
  • 5.) Untermenü in Menubar eintragen:
        $menu->entryconfigure('Datei', -menu => $menu_datei);


  • 6.) Bindungen zum Aufruf des Menüs erzeugen:
        $mw->bind('<Alt-d>', sub {$menu->postcascade('Datei');});
        $mw->bind('<Alt-b>', sub {$menu->postcascade('Bearbeiten');});
        $mw->bind('<Alt-h>', sub {$menu->postcascade('Hilfe');});
37
Besprechung zum Menü-System
  • So sieht das Programm aus:
38
Weitere Quellen
  • Empfehlenswertes Buch: „Mastering Perl/Tk“ von Steve Lidie und Nancy Walsh.
  • Perldoc: Zu allen Teilproblemen hilft einem meist ein entsprechender perldoc aufruf weiter.
  • Perl/Tk im Netz:
    http://www.perltk.org/
  • Onlinetutorial:
    http://wiki.perl-community.de/bin/view/Wissensbasis/PerlTkTutorial