Vor kaum zehn Jahren beherrschten graue Anwendungen den grauen Hintergrund des Unix-Desktops. Heute präsentieren sich KDE und Gnome mit moderner Oberfläche. Ihre Gestaltung verlangt ein geschultes Auge und guten Geschmack, beim Anzeigen und Erzeugen der Elemente hilft Tcls Werkzeugkasten.
Alte Unix-Hasen kennen sie noch aus ihrer Jugend, auch junge Linux-Freunde begegnen ihnen gelegentlich: klobige Anwendungen aus der X11-Steinzeit, mit kümmerlichen Toolkits ohne Rücksicht auf Bedienbarkeit und Aussehen entwickelt. Heute verdrängen aufgeputzte Applikationen diese Relikte vom Desktop und bringen frische Farben auf den Bildschirm. Wichtig für die Optik sind ansprechende Icons, die Knöpfe und Toolbars zieren. Gute Icons entwerfen ist eine Kunst; sie in Tk-Programmen zu verwenden dagegen leicht.
In den meisten Fällen gilt es, fertige Icons von der Festplatte zu laden und auf Labels und Buttons zu verwenden. Listing 1 zeigt alles Wesentliche in wenigen Zeilen, Abbildung 1 zeigt das Resultat. Zum Laden farbiger Bilder dient das »image«-Kommando:
image create photo Name -file Dateiname U -data Bildinhalt

Abbildung 1: Der Code in Listing 1 erzeugt drei Bilder, die in der ersten Zeile nebeneinander stehen. Darunter folgen zusammengesetzte Labels, die ein Bild mit Text kombinieren.
Dieser Befehl lädt entweder ein Icon aus einer Datei (mit der Option »-file«) oder die Bilddaten stehen direkt Base-64-kodiert im Befehlsaufruf (nach »-data«). Für jedes Icon erzeugt Tk ein Kommando, ganz wie von den Widgets bekannt. Den Namen dieses Kommandos kann der Programmierer vorgeben; verzichtet er darauf, wählt »image« selbst eine Bezeichnung und übergibt sie an den Aufrufer. Letzteres hat den Vorteil, dass dieses Verfahren nicht versehentlich ein vorhandenes Kommando überschreibt. Die Zeilen 5 bis 10 in Listing 1 zeigen mehrere Aufrufvarianten: Die erste gibt den Namen vor, während die anderen beiden diese Aufgabe Tk überlassen. Die Namen speichern sie in den Variablen »rolle« und »ident«. Weitere Optionen fasst Tabelle 1 zusammen.
Bilder im Skript einbetten
In vielen Fällen genügt es, Icons – wie in Zeile 6 und 8 gezeigt – aus einer Datei zu laden. Um die Installation einer Anwendung zu erleichtern, empfiehlt es sich aber, den Bildinhalt passend kodiert im Skript abzulegen. Folgende Zeilen laden ein Gif-Bild und wandeln es in einen Base-64-kodierten String:
package require Base64 set fd [open "icons/gnome-whoami.gif"] fconfigure $fd -translation binary set bild [::base64::encode [read $fd]] close $fd
Der String »$bild« enthält nun den Bildinhalt, den die Image-Option »-data« versteht. Einfach obige Befehle aufrufen, den String mit »puts $bild« ausgeben und den Zeichensalat in das Skript einfügen (vergleiche die gekürzte Zeile 10 in Listing 1). Diesen Trick nutzt auch Adrian Davis\’ Icons-Paket ([1] und Abbildung 2). Es verpackt Icons aus dem KDE-Projekt in einem großen Tcl-Skript. Wer dieses Skript in seine Tcl/Tk-Applikationen einbindet, kann bequem KDE-konforme Icons benutzen.
Das geladene Icon eignet sich für Labels, Buttons und Menü-Einträge sowie als eingebettetes Bild in Canvas- und Text-Widgets. Mit der Option »-image« zeigen Labels, Buttons und Menüfelder das gewünschte Icon, mit »-compound Anordnung« gleichzeitig Text und Icon. Mögliche Anordnungen sind »none« (nur Bild), »left« (Bild links des Textes), »right«, »bottom«, »top«, und »center« (Text und Bild zentriert übereinander). Die Zeilen 18 bis 22 (Listing 1) benutzen diese Option; in den unteren drei Vierteln von Abbildung 1 ist das Ergebnis zu sehen. Der Code darf ein geladenes Icon beliebig oft verwenden, auch das bestätigt sich in dem kleinen Programm.

Abbildung 2: Das Icons-Package von Adrian Davis enthält viele Symbolgrafiken aus dem KDE-Projekt. Das Paket bettet diese Bilder direkt in Tcl-Code ein.
|
Das Neueste |
|---|
|
Für die Sprache Tcl gibt es mehrere Interpreter: Neben der bekannten »tclsh« existiert eine reine Java-Implementation namens Jacl [10]. Mit Jim [11] ist ein weiterer Interpreter in Entwicklung. Seine Ziele sind geringer Speicherbedarf – unter 100 KByte – und ein modularer Aufbau, um sich auch für sehr kleine Computer wie Handhelds zu eignen. Aus einer ganz anderen Ecke kommt Parrot [12], die Basis von Perl 6. Bei Parrot soll der Teil zum Lesen der Quellen und Interpretieren getrennt sein, als Beispiel gibt es einen Tcl-Interpreter auf Parrot-Basis. Einstiegshilfen für Tcl mit Parrot finden sich im Wiki [13]. Das Problem der fehlenden PNG-Unterstützung in Tk geht Michael Kirkham mit Tk PNG [14] an. Anders als die im Artikel benutzte Img-Erweiterung bindet Tk PNG keine weiteren Bibliotheken ein. Michael möchte seine Erweiterung langfristig in den normalen Sprachumfang von Tk bringen. Wer sich mit VTK [9] zum Anzeigen von Daten aus Berechnungen und Messungen beschäftigen will, sollte Paraview [15] näher betrachten. Die leicht zu bedienende Oberfläche enthält viele VTK-Funktionen – das spart in vielen Fällen ein selbst geschriebenes Skript. PostgreSQL ist eine der besten freien SQL-Datenbanken und ihr Tcl-Support ist exzellent. Mit »pgtcl1.5« [16] unterstützt die bewährte Tcl-Erweiterung nun auch die Features der neuen PostgreSQL-Release 8.0. |
Formatwechsel
Dem normalen Image-Kommando fehlt leider die Unterstützung der verbreiteten Icon-Formate PNG und Jpeg, es liest nur Gif. Abhilfe bringt Jan Nijtmans\’ Img-Erweiterung [2]. Sie ist in den meisten Linux-Distributionen bereits enthalten; wer die Quellen selbst übersetzen will, findet die aktuelle Version 1.3 bei Sourceforge [3], dort heißt sie wegen eines Namenskonflikts Tkimg. Mit der Erweiterung zeigt Tk auch Icons und Grafiken in den Formaten Jpeg, PNG, Tiff, PPM, ICO, XPM, XBM oder PCX. Es genügt, in Zeile 3 von Listing 1 das Paket mit dem Kommando »package require Img« in den Interpreter zu laden.
Zudem fertigt Img auf Wunsch Screenshots von einzelnen Widgets an. Egal ob es auf ein einfaches Label oder eine komplexe Grafik im Canvas zielt, jedes GUI-Element findet damit seinen Weg in eine Bitmap-Datei. Besonders praktisch ist diese Technik, um dynamische Icons für HTML-Seiten zur Laufzeit zu erzeugen. Ein einfaches Beispiel ist in Listing 2 abgedruckt, es generiert ein PNG-Bild mit der aktuellen Uhrzeit.
|
Listing 1: Icons laden und |
|---|
01 #!/usr/bin/tclsh 02 package require Tk 03 04 # Bilder laden 05 image create photo password 06 -file [file join icons change-password-48.gif] 07 set rolle [image create photo 08 -file [file join icons lookandfeel-directory.gif] ] 09 set ident [image create photo 10 -data "R0lGODlhMAAwAOf/AAABAAACAAEEAAIFAQQHAgUIBAIJDAcJBQg.....] 11 12 # Bilder verwenden 13 label .password -image password 14 label .rolle -image $rolle 15 label .ident -image $ident 16 17 # Bild mit Text 18 label .identO -text "Oben" -image $ident -compound top 19 label .identL -text "Links" -image $ident -compound left 20 label .identZ -text "Mitte" -image $ident -compound center -fg white 21 label .identR -text "Rechts" -image $ident -compound right 22 label .identU -text "Unten" -image $ident -compound bottom 23 24 # Widgets platzieren 25 grid .rolle .password .ident 26 grid x .identO 27 grid .identL .identZ .identR 28 grid x .identU |
Warten vor dem Screenshot
Die Zeilen 6 bis 10 formen ein einfaches GUI mit einem Label und sorgen per »update idletasks« dafür, dass die Oberfläche am Bildschirm erscheint, bevor das Programm weiter abläuft. Ohne Zeile 10 würde Tk warten, bis das Programm in der Eventschleife landet – so vermeidet es, dass die Anzeige flackert, während das Programm Widgets einfügt – und der Aufruf in Zeile 13 würde scheitern. Die letzten beiden Zeilen schießen ein Bildschirmfoto des Labels und schreiben es mit »$image write -format Format Dateiname« auf die Festplatte.
Leider braucht Tk Verbindung zu einem X-Server, damit dieser Trick klappt. Auf einem Webserver läuft er allerdings meist nicht. Als einfacher Ausweg eignet sich ein virtueller X-Server mit VNC, der ohne Bildschirm und Grafikkarte auf jedem Server startet:
vncserver -name Hostname:42 wish listing2.tcl -display Hostname:42 vncserver -kill Hostname:42
Mit dem »image«-Kommando liefert Tk zwar keine komplette Bildbearbeitung, es eignet sich aber für viele Standardaufgaben. Beispielsweise ändert ein einfacher Aufruf die Farbe und Transparenz eines einzelnen Pixels. Das Tcl-Wiki enthält viele Beispiele [4] für Bildbearbeitungen, sie reichen vom einfachen Zusammenbau bestehender Icons bis zu umfangreichen Operationen wie Schärfen oder Farbmanipulation.
|
Listing 2: Bilder |
|---|
01 #!/usr/bin/tclsh
02 package require Tk
03 package require Img
04
05 # GUI erzeugen und auf den Bildschirm bringen
06 set uhrzeit [clock format [clock seconds] -format "%H:%M:%S"]
07 label .l -text $uhrzeit -font {Palatino 24 bold} -bg white
08 pack .l
09 wm geometry . +100+100
10 update idletasks
11
12 # Bildschirmfoto schießen und speichern
13 set image [image create photo -format window -data .l]
14 $image write -format png "uhrzeit.png"
|
Montagearbeit
Viele Anwendungen montieren neue Icons aus mehreren bestehenden Bildern, zum Beispiel signalisieren verschiedenfarbige Flächen einen Status oder kleine Dreiecke kennzeichnen einen Verzeichnisknoten. Zeile 7 in Listing 3 lädt ein kleines Dreieck aus einem PNG-Bild, um es in ein anders Icon (Zeile 6) einzufügen: Das Image-Subkommando »copy« kopiert die Bilddaten eines Icons in ein anderes.
|
Listing 3: |
|---|
01 #!/usr/bin/tclsh 02 package require Tk 03 package require Img 04 05 # Basis-Icons laden 06 image create photo basis -file [file join icons emblem-people.png] 07 image create photo dreieck -file [file join icons dreieck.png] 08 09 # Zusammenfügen durch Addieren 10 image create photo kombi 11 kombi copy basis -to 0 0 12 kombi copy dreieck -to 15 15 13 14 # Zusammenfügen durch Überschreiben 15 image create photo kombi2 16 kombi2 copy basis -to 0 0 17 kombi2 copy dreieck -to 15 15 -compositingrule set 18 19 # Statusanzeige 20 image create photo status 21 status put red -to 0 0 15 15 22 status copy basis -to 4 4 23 24 # Darstellung 25 label .dreieck -image dreieck -text "Dreieck" -compound top 26 label .basis -image basis -text "Basis" -compound top 27 label .kombi -image kombi -text "Zusammen" -compound top 28 label .kombi2 -image kombi2 -text "Zusammen mit set" -compound top 29 label .status -image status -text "Statusanzeige" -compound top 30 grid .dreieck .basis .kombi .kombi2 .status -padx 10 -sticky s |
Per Default überlagert das Kommando die vorhandenen Bilddaten mit den neuen (Zeilen 11, 12 und 16) und berücksichtigt dabei transparente Flächen. Mit der Option »-compositingrule set« (Zeile 17) überschreibt es vorhandene Bilddaten. Auch einfache Zeichenoperationen sind möglich; Zeile 21 färbt eine rechteckige Fläche rot ein. Das Ergebnis ist in Abbildung 3 zu sehen. Die Operationen laufen so schnell, dass sie problemlos zur Laufzeit erfolgen dürfen. Das reduziert oft die Anzahl der benötigten Icon-Dateien enorm.

Abbildung 3: Der Code in Listing 3 kombiniert neue Icons aus vorhandenen Bildern: Dreieck und Basis ergeben zusammen das dritte Icon. Nummer vier zeigt eine andere Kombinationstechnik. Das rote Rechteck im Icon rechts entsteht durch ein weiteres Image-Kommando.
Viele modern getrimmte Anwendungen sprengen den Rahmen des Windowmanagers und nehmen beliebige Formen an. Technische Basis sind die X-Shape-Extensions, sie erlauben unter X11 beliebige Fensterformen. Mit dem WMX-Paket von Rildo Pragana gelingt das auch mit Tk. Auf seiner Webseite [5] verteilt er ein fertiges Starkit [6], das neben einem Beispiel die Quellen sowie eine fertig kompilierte Linux-Version enthält. In den Download-Beispielen für diesen Artikel [17] ist es bereits enthalten.
Rahmenlos

Abbildung 4: Beliebig geformte Fenster sind dank WMX-Erweiterung auch mit Tcl/Tk möglich. Die Zeiger dieser realistisch wirkenden Uhr ticken im Zehntelsekundentakt.
Der Screenshot in Abbildung 4 zeigt das Ergebnis von Listing 4. Hierzu wurde eine Armbanduhr gescannt, mit Gimp das Armband und die Zeiger entfernt sowie die Uhr freigestellt, also alles außerhalb der Uhr als transparent definiert. Die Zeilen 8 bis 12 von Listing 4 produzieren ein gewöhnliches Fenster, in dem ein Canvas-Widget mit dem Uhrenbild steckt. Das Canvas nimmt später auch die Zeiger auf.
|
Listing 4: Krumme |
|---|
01 #!/usr/bin/tclsh
02 lappend auto_path wmx
03 package require Tk
04 package require wmx
05 package require Img
06
07 # Bild im Fenster mit einem Canvas
08 image create photo uhr -file [file join icons uhr.png]
09 canvas .c
10 .c create image 0 0 -image uhr -anchor nw
11 pack .c -fill both -expand true
12 wm geometry . 273x250
13 setXwinshape . uhr
14
15 # Fenster verschieben und schließen
16 bind . <1> {
17 set x [expr {[winfo rootx .] - %X}]
18 set y [expr {[winfo rooty .] - %Y}]
19 }
20 bind . <B1-Motion> {
21 wm geometry . +[expr {%X+$x}]+[expr {%Y+$y}]
22 }
23 bind . <Control-q> {
24 exit 0
25 }
26
27 # Zeiger zeichnen
28 proc malZeiger {winkel radius dicke xoff yoff} {
29 set id [.c create line 0 0
30 [expr {cos($winkel) * $radius}]
31 [expr {sin($winkel) * $radius}]
32 -fill black -width $dicke -tag zeiger]
33 .c move $id $xoff $yoff
34 }
35
36 # Drei Zeiger zeichnen
37 proc malZeit {} {
38 set t [clock seconds]
39 scan [clock format $t -format %I] %d std
40 scan [clock format $t -format %M] %d min
41 scan [clock format $t -format %s] %d sec
42 set PI [expr {2*acos(0)}]
43
44 .c delete zeiger
45
46 set winkel [expr {($sec -15)/30.0 * $PI}]
47 malZeiger $winkel 27 2 127 171
48
49 set winkel [expr {($min -15)/30.0 * $PI}]
50 malZeiger $winkel 100 2 127 125
51
52 set winkel [expr {($std -2)/6.0 * $PI}]
53 malZeiger $winkel 80 3 127 125
54
55 # In 100 Millisekunden neue Zeigerposition
56 after 1000 malZeit
57 }
59 malZeit
|
Damit nur die Uhr sichtbar ist und nicht ein normales rechteckiges Fenster, gibt »setXwinshape Fenster Bild« eine Maske an. Nur die nicht transparenten Bereiche der Maske gehören fortan zum sichtbaren Bereich des Fensters, die transparenten Stellen verbirgt X11. Zeile 13 verwendet das Uhrenbild als Maske.
Da der Windowmanager keine Fensterdekoration mehr anbringt, muss sich das Programm selbst um Funktionen wie Schließen und Verschieben kümmern. Dazu dienen drei »bind«-Aufrufe in den Zeilen 16 bis 25. Bei gedrückter linker Maustaste ist die Uhr auf dem Bildschirm verschiebbar, ein Druck auf [Strg]+[Q] beendet die Anwendung.
Die »malZeiger«-Prozedur ab Zeile 28 zeichnet einen Uhrzeiger mit den normalen Canvas-Befehlen. Spannend ist die »malZeit«-Funktion ab Zeile 37: Sie berechnet die Winkel aller Zeiger und sorgt per »after«-Aufruf (Zeile 56) dafür, dass der Chronograph alle 100 Millisekunden auf den aktuellen Stand kommt.
Die WMX-Erweiterung funktioniert leider nur unter X11. Wer zusätzlich für Windows programmiert, findet in der Shape-Extension [7] von Donal K. Fellows vergleichbare Features. Shape arbeitet unter X11 und Windows.
Grenzenlos
Dem Verwenden, Ändern oder Erzeugen von Icons setzt Tk kaum Grenzen. Braucht eine Webapplikation zur Laufzeit neue Icons, ist der VNC-Trick allerdings verpönt. Dann bietet sich die Tclgd-Erweiterung von Michael Schwartz an. Sie nutzt die bewährte GD-Bibliothek, um in Tcl-Programmen aufwändige Grafiken zu erstellen.
Wer bei Icons eher an hochauflösende Bilder aus Scanner oder der Radiologie denkt, ist bei VTK [9] gut aufgehoben. Es hat viele Methoden implementiert, um große Bilder zu ver- und bearbeiten (siehe auch Kasten “Das Neueste”).
Version 8.5
Ungefähr zum Erscheinen der nächsten Federlesen-Folge soll die neue Tcl-Version 8.5 fertig sein. Passend zu diesem Ereignis werden dann die neuen Möglichkeiten von Tcl und der Tile-Bibliothek Thema sein. (fjl)
|
Infos |
|---|
|
[1] Icons-Paket mit eingebetteten Symbolen: [http://www.satisoft.com/tcltk/icons/] [2] Jan Nijtmans Img-Erweiterung: [http://www.xs4all.nl/~nijtmans/img.html] [3] Tkimg-Erweiterung auf Sourceforge: [http://sourceforge.net/projects/tkimg/] [4] Suche nach Tcl-Wiki-Seiten zum Imagepaket: [http://wiki.tcl.tk/2?image] [5] Rildo Pragana, “WMX – Shaped and managed tk toplevels”: [http://www.pragana.net/othersoft.html#wmx] [6] Carsten Zerbst, “Stern-Gucker – Tcl-Module zu einer ausführbaren Datei verschnüren”: Linux-Magazin 01/04, S. 100 [7] Shape-Extension: [http://www.cs.man.ac.uk/~fellowsd/tcl/shapeidx.html] [8] Tcl-GD: [http://www.du.edu/~mschwart/tclextensions.html#gdTbl] [9] VTK, Visulization Toolkit: [http://public.kitware.com/VTK/] [10] Jacl, ein Tcl-Interpreter nur in Java: [http://www.tcl.tk/software/java/] [11] Jim: [http://jim.berlios.de] [12] Parrot: [http://www.parrotcode.org] [13] Parrot im Tcl-Wiki: [http://wiki.tcl.tk/7148] [14] Tk PNG: [http://www.muonics.com/FreeStuff/TkPNG/] [15] Paraview, GUI-Frontend für VTK: [http://www.paraview.org] [16] Pg TCL, das Tcl-Interface für PostgreSQL: [http://pgfoundry.org/projects/pgtcl/] [17] Dateien auf dem Linux-Magazin-FTP-Server: [ftp://ftp.linux-magazin.de/pub/magazin/2005/07/Federlesen] |






