Aus Linux-Magazin 10/2001

Benutzerfreundlich durch dynamische Menüs und L10n

Wenn ein Programm freundlich zu seinen Benutzern sein will, dann sollte es auch deren Sprache sprechen. Die Lokalisierung sieht Tcl/Tk bereits im Basispaket vor. Dynamische Menüs machen Applikationen für ihre Benutzer intuitiv bedienbar.

Menüs sind einer der wichtigsten Bestandteile aller grafischen Oberflächen, hinter ihnen verbirgt sich meist ein großer Teil der ganzen Anwendungslogik. Diese Folge der Feder-Lesen-Reihe beschreibt, wie Menüs in Tcl/Tk erzeugt werden und welche Möglichkeiten das Toolkit dabei den Programmierern zur Verfügung stellt. Ein weiterer Punkt ist das Internationalisieren und Lokalisieren von Tk-Anwendungen. All dies ist mit dem normalen Umfang von Tcl/Tk möglich, zusätzlichen Pakete sind dafür nicht erforderlich.

In Tk erzeugt der Befehl »menu« alle Arten von Menüs, unabhängig davon, ob es sich um ganze Menüleisten, Untermenüs oder Popup-Menüs handelt. Wie alle anderen Widgets auch lassen sich Menüs mit den Layout-Managern Grid, Pack oder Place anordnen. Besser und einfacher ist es allerdings, die Menüleiste an ein Fenster zu hängen:

. configure -menu .menu

Dieses Beispiel fügt das Menü ».menu« als Menüleiste an das Hauptfenster an. Wie die Abbildungen 1 bis 3 zeigen, ordnet Tk dann die Menüleiste dem jeweiligen Styleguide entsprechend an, passend zum Betriebssystem, auf dem die Applikation läuft. Beispielsweise ist unter Linux das Hilfe-Menü rechtsbündig angeordnet, während es unter Windows linksbündig an die anderen Menüpunkte anschließt. Beim Macintosh sitzt die Menüleiste der aktuellen Anwendung am oberen Rand des Desktops.

Menü im Menü

Eine Menüleiste enthält eine Reihe von Untermenüs. Die Untermenüs enthalten die eigentlichen Einträge wie Kommandos, Radio- oder Checkbuttons oder weitere Untermenüs. Diese Einträge können mit den Menü-Widget-Methoden »add«, »configure« und »delete« eingehängt und bearbeitet werden. Das Beispiel in Listing 1 erzeugt die Menüleiste und hängt dann drei Untermenüs ein.

Die Beschriftung der Menüs ist wichtiger, als mancher Programmierer vielleicht denkt, er sollte sich also die Auswahl seiner Wörter und Begriffe sehr genau überlegen. Einerseits steht wenig Platz zur Verfügung (maximal zwei bis drei Wörter), andererseits sollte die Beschreibung sehr exakt und unmissverständlich sein. Statt des Textes können Menüs aber auch ein Bild anzeigen, wie hier im Hilfemenü geschehen (siehe Abbildung 3).

Viele Anwender wollen bei der Arbeit die Finger auf der Tastatur behalten können und nicht ständig zur Maus greifen. Die Menüs öffnen sie dann mit der [Alt]-Taste und einer zusätzlichen, meist unterstrichen dargestellten Buchstaben-Taste. Im Beispiel ist dieses Verfahren beim Bearbeiten- und beim Hilfe-Menü realisiert. Mit der Option »-underline Position« erfährt Tk, welchen Buchstaben es unterstreichen soll. Dieser Buchstabe dient dann auch zum Öffnen des Untermenüs. Tk erzeugt die entsprechenden Bindings automatisch.

Abbildung 1: MacOS 9 zeigt die Menüs nicht im jeweiligen Fenster, sondern immer am oberen Bildschirmrand an. Auch Tk hält sich an diese Konvention; sogar das Abreißen der Menüs ist implementiert.

Abbildung 1: MacOS 9 zeigt die Menüs nicht im jeweiligen Fenster, sondern immer am oberen Bildschirmrand an. Auch Tk hält sich an diese Konvention; sogar das Abreißen der Menüs ist implementiert.

Menüs abreißen

Einige Anwendungen nutzen so genannte abreißbare Menüs, also Menüs, die sich von der Hauptanwendung trennen lassen. Ein prominentes Beispiel hierfür ist Gimp. Bei Tk-Menüs ist das Abreißen per Default ebenfalls möglich, es lässt sich aber auch mit der Option »-tearoff 0« verhindern.

Kontextsensitive Menüs können eine Anwendung benutzerfreundlicher gestalten. Sie stellen je nach dem aktuellen Umfeld (also dem Kontext) nur jene Kommandos zur Verfügung, deren Einsatz zurzeit auch sinnvoll ist. Alle anderen Kommandos zeigt Tk dagegen nur in grauer Schrift an. Der Anwender weiß durch diese Darstellung, welche Kommandos vorhanden sind und welche davon er im Moment nutzen kann.

Den aktuellen Zustand eines Menüeintrags legt die Option »-state Zustand« fest. Im Normalfall ist ein Kommando »normal«, im Zustand »disabled« ist es grau und kann nicht gewählt werden.

Kontextsensitive Menüs

Aber wie werden Menüs kontextsensitiv? Am einfachsten dadurch, dass das Programm sie bei jedem Öffnen neu erzeugt. Die Option »-postcommand Befehl« der Menü-Widgets ist hierfür geeignet: Den Befehl ruft Tk vor dem Öffnen des Menüs auf. Üblicherweise dauert das Erzeugen eines Untermenüs weniger als eine Millisekunde, die Verzögerungen stören also nicht. Die einzelnen Menü-Einträge erzeugt das Skript dann einfach mit dem entsprechenden Modus. An seine Grenzen stößt dieses einfache Verfahren allerdings bei abgerissenen Menüs: Sie sind immer geöffnet und ändern den Zustand erst dann, wenn das Menü aus der Menüleiste wieder geöffnet wird.

Ähnlich hilfreich wie kontextsensitive Menüs sind Popup-Menüs. Sie sind meist über die rechte Maustaste erreichbar und stellen dem Benutzer in speziellen Bereichen der Anwendungen wichtige Kommandos zur Verfügung, die speziell für den jeweiligen Bereich gelten. Um ein Popup-Menü an einer beliebigen Stelle der Anwendung zu öffnen, gibt es das Kommando »tk_popup Menü x y«.

Das in Listing 1 angeführte Beispiel erzeugt einen aktiven Bereich (siehe auch Abbildung 3), in dem die rechte Maustaste das Popup-Menü öffnet. Hierzu ist übrigens kein zusätzliches Menü nötig, das vorhandene Bearbeiten-Menü wird einfach wiederverwendet.

Abbildung 2: Unter Windows hebt sich die Menüleiste nicht vom Rest der Applikation ab, wenn das Programm keine eigene Hintergrundfarbe hat. Die unterstrichenen Buchstaben dienen als Shortcut zum Öffnen des Menüs.

Abbildung 2: Unter Windows hebt sich die Menüleiste nicht vom Rest der Applikation ab, wenn das Programm keine eigene Hintergrundfarbe hat. Die unterstrichenen Buchstaben dienen als Shortcut zum Öffnen des Menüs.

Abbildung 3: Tk zeichnet seine Menüs unter Linux im bekannten Motif-Look - die Menüleiste ist dreidimensional abgehoben. Das Hilfe-Menü steht immer am rechten Rand der Menüleiste.

Abbildung 3: Tk zeichnet seine Menüs unter Linux im bekannten Motif-Look – die Menüleiste ist dreidimensional abgehoben. Das Hilfe-Menü steht immer am rechten Rand der Menüleiste.

Listing 1: Menüs mit Tk erzeugen

#!/bin/sh
#
# Beispiel für Menüs mit Tk 
exec wish $0 $@

# Menü-Balken erzeugen

menu .menu
# ... und mit Hauptfenster verbinden
. configure -menu .menu

# Die Untermenüs

# Einfaches Untermenü
.menu add cascade -label Datei 
    -menu .menu.file
# Untermenü mit Shortcut <ALT-e>
.menu add cascade -label Bearbeiten 
    -menu .menu.edit -underline 1
# Untermenü mit Shortcut <ALT-H>
.menu add cascade -label Hilfe 
    -menu .menu.help -underline 0

# Das Datei-Menü

menu .menu.file
# ... mit Einträgen für Kommandos
.menu.file add command -label Öffnen
# ... und eine Unterteilung
.menu.file add separator
.menu.file add command -label Beenden 
    -command "exit" -accelerator "^q"
# Das Binding zum Beenden
bind . <Control-q> exit<c># Das Hilfe-Menü (nicht ablösbar)

menu .menu.help -tearoff 0
.menu.help add command -bitmap info

# Das (kontextsensitive) Bearbeiten-Menü

menu .menu.edit -postcommand menuBearb
set kontext normal

# Die Prozedur zum Erzeugen des Bearbeiten-Menüs

proc menuBearb {} {
    .menu.edit delete 0 end
    .menu.edit add command 
        -label "Abhängiger Befehl" 
        -state $::kontext
    .menu.edit add separator
    .menu.edit add radiobutton -label An 
        -value normal -variable ::kontext
    .menu.edit add radiobutton -label Aus 
        -value disabled -variable ::kontext
}

# Aktiver Bereich mit anderem Cursor

frame .a
grid .a
label .a.b -font {Sans 30 bold} 
    -cursor crosshair -text "Aktiver Bereich"
grid .a.b -padx 25 -pady 25

# Das Binding zum Öffnen des Popup-Menüs

bind .a.b <Button-3> {
    tk_popup .menu.edit %X %Y
}

Listing 2: Lokalisierung mit Tk

#!/bin/sh
# Beispiel für die Lokalisierung
# von Tcl-Anwendungen 
exec wish $0 $@

package require msgcat

# Auslesen der Systemeinstellung
msgcat::mclocale $env(LANG)

# Laden der Sprachkataloge
msgcat::mcload [pwd]

# Aufbau des GUIs
label .l -text [msgcat::mc "Default is %s" $env(LANG)]
grid .l
label .l2 -text [msgcat::mc date 10 15]
grid .l2
button .b -text [msgcat::mc "Exit"] -command exit
grid .b -padx 5 -pady 5

wm geometry . 220x75
wm title . "Deutsch"
#wm title . "English"

Listing 3: Deutsche Meldungen

msgcat::mcset de "Default is %s" 
    "Systemeinstellung ist %s"
msgcat::mcset de date 
    "Beispieldatum %2$i.%1$i (Tag, Monat)"
msgcat::mcset de "Exit" "Beenden"

Listing 4: Englischer Katalog

msgcat::mcset en date "Date %i.%i (month, day)"

Abkürzung über die Tastatur

Je häufiger man mit einer Anwendung arbeitet, desto eher kommt der Wunsch nach Abkürzungen auf. Die eben beschriebenen Popup-Menüs helfen hier schon weiter. Aber statt sich jedes Mal durch verschiedene Menüs zu hangeln, kommt man mit einer Tastenkombination (Shortcut) schneller zum Ziel.

Damit ein Anwender diese Shortcuts schnell lernen kann, bietet es sich an, diese Kürzel neben den entsprechenden Menü-Eintrag zu schreiben. Das kann mit der Option »-accelerator Shortcut« geschehen. Dabei sollte der Programmierer aber darauf achten, die üblichen Shortcuts nicht für eigene Zwecke zu verwenden. Von [Strg]+[q] etwa erwartet jeder Anwender, dass er damit die Anwendung beendet.

Anders als bei der Option »-underline« muss das Binding für Shortcuts extra mit dem Befehl »bind« erzeugt werden. Bei einer größeren Anzahl solcher Befehle bietet sich auch ein Blick auf die mächtigen virtuellen Events an.

Tk mehrsprachig

Nicht nur in Menüs, auch in vielen anderen Bereichen einer Anwendung wird Text angezeigt. Da aber nicht alle Anwender Deutsch sprechen und Englisch als Lingua franca auch nicht das Maß aller Dinge ist, sollte die Oberfläche in mehreren Sprachen zur Verfügung stehen. Das wird als Lokalisierung oder L10n bezeichnet. Unter Tcl bietet sich hierfür das Msgcat-Paket an. Es gehört zum normalen Umfang von Tcl und wird im künftigen Tcl 8.4 auch für die Systemmeldungen eingesetzt. Msgcat nutzt Kataloge, die für die verschiedenen Beschriftungen oder Ausgaben jeweils die Übersetzungen enthalten.

Die Verwendung des Msgcat-Pakets zeigt ein einfaches Beispiel in Listing 2. Der Übersetzungskatalog für Deutsch muss in der Datei »de.msg« stehen (siehe Listing 3), die englischen Meldungen sind in »en.msg« enthalten (siehe Listing 4). Zuerst stellt das Beispiel die gewünschte Sprache (Locale) ein, das geschieht mit »msgcat::mclocale Locale«. Die Locales werden mit den Länderkürzeln nach ISO 639 [1] bezeichnet. Die Benutzereinstellung findet man üblicherweise in der Umgebungsvariable »LANG«.

Als Nächstes sind die Sprachkataloge zu laden. Dies erfolgt mit dem Befehl »msgcat::mcload Verzeichnis«. Im angegebenen Verzeichnis sollte sich pro Sprache eine Datei mit der jeweiligen Übersetzung befinden. Die Dateinamen setzen sich aus dem Länderkürzel und der Endung ».msg« zusammen. In diesen Dateien steht eine Reihe von Befehlen der Art »msgcat::mcset Sprache OriginalÜbersetzung“«.

Abbildung 4: Zur Lokalisierung gehört auch, dass im Englischen der Monat vor dem Tag steht, im Deutschen aber genau umgekehrt der Tag vor dem Monat.

Abbildung 4: Zur Lokalisierung gehört auch, dass im Englischen der Monat vor dem Tag steht, im Deutschen aber genau umgekehrt der Tag vor dem Monat.

Ein Katalog für jede Sprache

Mit dem speziellen Editor MSGedit [2] lassen sich diese Dateien sehr einfach erstellen. In der lokalisierten Anwendung selbst muss einfach jede Zeichenkette für eine Meldung oder Beschriftung durch den Aufruf von »[msgcat::mc ” Original“]« ersetzt werden. Das Kommando gibt die Übersetzung aus dem gewählten Katalog zurück. Findet sich keine Übersetzung, gibt »msgcat:mc« die ursprüngliche Zeichenkette zurück, so dass die Anwendung bedienbar bleibt. Für die Originalsprache ist der Katalog daher fast leer (siehe Listing 4).

In vielen Fällen genügt das aber noch nicht: Meldungen setzen sich oft aus einem festen und einem dynamischen Anteil zusammen. Die Übersetzungen können daher Formatierungsbefehle enthalten. Das geht sogar so weit, dass die Reihenfolge dynamischer Anteile sich zwischen den verschiedenen Sprachen unterscheiden kann. Im Beispiel wird das benutzt, um das Datum in der richtigen Reihenfolge auszugeben, also einmal Tag, Monat und einmal umgekehrt (siehe Abbildung 4).

Abhängig von der Umgebungsvariablen »LANG« startet die Anwendung mit einer englischen (»en«) oder einer deutschen Oberfläche (»de«). In der Tcsh wird diese Einstellung mit »setenv LANG en« vorgenommen, in der Bash mit »LANG=en«. Eventuell ist noch ein Export nötig.

Mit den hier vorgestellten Mitteln lassen sich schon sehr benutzerfreundliche Oberflächen erstellen. Darüber hinaus gibt es beispielsweise noch Hilfe-Ballons, auch Tooltips genannt. Deren Realisierung ist in [3] beschrieben, die BWidgets [4] enthalten bereits ein passendes Widget.

Nach diesem Exkurs an die Oberfläche beschreibt das nächste Feder-Lesen, wie sich mit VTK Visualisierungen erstellen lassen. (fjl)

Neues aus der Tcl-Welt

Seit dem vorigen Feder-Lesen ist trotz Sommerpause eine ganze Menge passiert. Vor kurzem ging die OSCON zu Ende – auf dieser Konferenz gab es natürlich auch einen Tcl-Track. Die Papers zu den Vorträgen sind unter [5] zu finden. Unter anderem wurde gesprochene Sprache als Ein- und Ausgabe für Anwendungen behandelt. Der Schwerpunkt war jedoch die Integration von Tcl in Anwendungen für ECAD, eine der Domänen von Tcl.

Tcl-Distribution von Active State

Pünktlich zur OSCON veröffentlichte Active State eine eigene Tcl-Distribution. Das im entpackten Zustand ganze 31 MByte große Paket enthält neben dem eigentlichen Interpreter wichtige Erweiterungen, unter anderem [incr Tcl], TclX, Expect, Tcllib und die Tkcon. Das Paket wird zudem mit einem Installationsprogramm geliefert und dürfte zurzeit der einfachste Weg zu einer All-inclusive-Installation von Tcl/Tk sein.

Die Einzelteile gibt es natürlich nach wie vor frei im Netz. Besonders erwähnenswert sind dabei die Tcllib und die BWidgets. Beide sind bei Sourceforge [4] in einem gemeinsamen Projekt erhältlich. Die Tcllib besteht aus mehreren Modulen für die täglichen Probleme, etwa Base64-Encoding, MIME-Behandlung oder POP3- und FTP-Zugriff. Ebenso wie die BWidgets ist die Tcllib selbst in Tcl geschrieben und kommt ohne Kompilieren aus.

Die BWidgets sind eine praktische Sammlung von Widgets, die im normalen Tk fehlen (siehe Abbildung 5). Alle neuen Widgets sind nur mit Hilfe der vorhandenen Tk-Widgets aufgebaut (so genannte Mega-Widgets). Das Paket enthält unter anderem eine Combobox, ein Tree-Widget, ein Notebook-WIdget und eine Spinbox, zudem unterstützt es Drag & Drop.

Große Pläne

Das Tcl-Core-Team diskutiert zurzeit darüber, neue Widgets und zusätzliche Optionen in Tk zu integrieren. In vielen Fällen ist auch schon eine Implementierung vorhanden. Eine weitere, sehr kontrovers geführte Diskussion behandelt die Integration von [incr Tcl] in das normale Tcl.

Als weiterer Punkt wird Theming-Unterstützung für Tk diskutiert, in dieser Hinsicht hinkt Tk weit hinter Gtk oder Qt her. Wer trotzdem heute schon Themes mit Tcl verwenden will, kann auf Peter Baums Gnocl [6] zurückgreifen, damit lassen sich die Gtk- und Gnome-Widgets nutzen.

PDA-taugliche Applikationen

Speziell für den Linux-PDA Agenda hat Alexander Caldwell einen kleinen Browser und einen E-Mail-Client geschrieben [7]. Beide Applikationen sind auf die doch eingeschränkten Möglichkeiten eines PDAs abgestimmt. Interpreter-Sprachen machen gerade in dieser Umgebung sehr viel Sinn: Statt mehrerer Anwendungen genügt ein Interpreter zur Laufzeit. Die Skripte können auch komprimiert gespeichert werden, wobei sich Skripte meist deutlich stärker komprimieren lassen als Binärprogramme. Bei Etlinux [8] steuern Tcl-Skripte sogar den ganzen Bootvorgang.

Abbildung 5: Die BWidgets enthalten neue Widgets für Tk. Tree, Paned Window, Combobox, Notebook, Spinbox und Progress Dlg gehören zur Standardausstattung vieler moderner Oberflächen.

Abbildung 5: Die BWidgets enthalten neue Widgets für Tk. Tree, Paned Window, Combobox, Notebook, Spinbox und Progress Dlg gehören zur Standardausstattung vieler moderner Oberflächen.

Der Autor

Carsten Zerbst ist wissenschaftlicher Mitarbeiter an der TU-HH. Neben der Forschung über die Dienstintegration an Bord von Schiffen beschäftigt er sich mit Tcl in allen Lebenslagen. Ab Oktober sucht er neue Aufgaben im Unix/Linux-Umfeld.

Infos

[1] Ländercodes nach ISO 639: [http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_639.html]

[2] MSGedit: [http://www.tu-harburg.de/~skfcz/tcltk.html]

[3] Ballonhelp: [http://purl.org/thecliff/tcl/wiki/534.html]

[4] Tcllib, BWidgets: [http://sourceforge.net/projects/tcllib/]

[5] OSCON-Tcl-Papers: [ftp://ftp.oreilly.com/pub/conference/os2001/tcl_papers]

[6] Gnocl: [http://www.dr-baum.net/gnocl/]

[7] Agenda-Web-Browser: [http://www.psnw.com/~alcald/tiny_tcl_web_browser.html]

[8] Etlinux: [http://www.etlinux.org/]

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben