Im zweiten Teil dieses Widgets-Tutorials (hier der Link zum ersten Teil) möchte ich Euch weitere Widgets vorstellen, die Ihr mit Shoes, dem kleinen, palttformübergreifenden GUI- und Graphik-Toolkit für Ruby erstellen könnt. Es geht dabei um Radiobutton, Checkboxen und als ganz neues und aktuelles Widget, einen Slider.
Radiobuttons sind (meist runde) Knöpfe, die gruppiert sind und von denen sich je Gruppe nur einer »ankreuzen«, das heißt aktiv schalten läßt. Darin ähneln sie Listboxen, wie ich sie im GUI95-Tutorial zu Shoes schon eingesetzt hatte. Radiobuttons sind – im Prinzip – in Shoes recht einfach zu implementieren:
# encoding: utf-8
Shoes.app do
para "Welcher dieser Klassiker der Reiseliteratur ist Dein Favorit?\n"
radio; para "Spaziergang nach Syrakus\n"
radio; para "Die italienische Reise\n"
radio; para "Ein Pyrenäenbuch\n"
end
Dieses Progrämmchen ergibt diesen Output, der sich tatsächlich wie gewünscht verhält:
Sobald man eine Aauswahl trifft, wird eine andere, eventuell vorher aktivierte Auswahl wieder inaktiv. Es gibt immer nur eine aktive Auswahl. Das funktioniert aber nur, weil alle Radiobutton in einem Slot (zusammen mit einer Menge an para
) zusammengefaßt sind. Ändert man obiges Progrämmchen nur leicht in
# encoding: utf-8
Shoes.app do
stack do
para "Welcher dieser Klassiker der Reiseliteratur ist Dein Favorit?"
flow {radio; para "Spaziergang nach Syrakus"}
flow {radio; para "Die italienische Reise"}
flow {radio; para "Ein Pyrenäenbuch"}
end
end
sieht der Output optisch fast genau so aus, nur Ihr könnt auf einmal mehr als eines der runden Knöpfchen ankreuzen. Das passiert, weil nun jeder Radio-Button in einem eigenen flow
-Slot isoliert ist.
Natürlich kennt Shoes dafür eine Lösung. Ihr müßt den Buttons nur mitteilen, daß sie zu einer Gruppe gehören, zum Beispiel zur :books
-Gruppe
# encoding: utf-8
Shoes.app do
stack do
para "Welcher dieser Klassiker der Reiseliteratur ist Dein Favorit?"
flow do
radio :books
para "Spaziergang nach Syrakus"
end
flow do
radio :books
para "Die italienische Reise"
end
flow do
radio :books
para "Ein Pyrenäenbuch"
end
end
end
und schon verhalten sich die Knöpfchen wieder wie gewünscht.
Nun sind aber GUI-Elemente recht sinnlos, wenn sie nicht mit dem Rest des Programms interagieren können. Das möchte ich als nächstes in einer kurzen Anwendung zeigen:
Ich stelle wieder die Frage nach dem beliebtesten Buch aus dem Kanon der Klassiker der Reiseliteratur und Shoes antwortet, welches Buch Euer Favorit ist. Das Pyrenäenbuch von Kurt Tucholsky habe ich nicht nur aufgenommen, weil es wirklich eines meiner Favoriten ist, sondern natürlich auch, weil es einen Umlaut enthält und ich zeigen wollte, daß Shoes völlig problemlos mit diesen Umlauten umgehen kann.
Um das gewünschte Verhalten zu erreichen und um den Quellcode klein zu halten, habe ich das Skript ein wenig umgestellt:
# encoding: utf-8
Shoes.app do
@list = ["Spaziergang nach Syrakus", "Die italienische Reise", "Ein Pyrenäenbuch"]
para "Welcher dieser Klassiker der Reiseliteratur ist Dein Favorit?"
stack do
@list.map! do |name|
flow {@r = radio :books; para name}
[@r, name]
end
button "Deine Auswahl?" do
selected = @list.map {|r, name| name if r.checked?}.compact
alert selected.join if not selected.empty?
end
end
end
Auch wenn ich die Beschäftigung mit Shoes eigentlich nur angefangen habe, weil ich mir Ruby beibringen wollte, geht ein Crash-Kurs in Ruby über das hinaus, was diese kleine Shoes-Tutorial-Reihe leisten kann. Trotzdem möchte ich auf einige Einzelheiten des Skriptes eingehen:
Als erstes habe ich die möglichen Auswahlelemente in eine Liste gepackt, so daß ich in einer Schleife, einer Iteration über diese Liste, die einzelnen Radiobuttons und ihre Beschriftung erzeugen kann. Änderungen an der Liste der Bücher müssen so nur an einer Stelle vorgenommen werden. Wenn Ihr also Theodor Fontanes »Wanderungen durch die Mark Brandenburg« in die Auswahl aufnehmen wollt, müßt Ihr sie nur in diese Liste einfügen. Probiert es aus, das Programm verhält sich dann wie erwartet.
Dann gibt es ein wenig syntaktischen Zucker oder auch Ruby-Folklore in den Namenskonventionen von Methoden: Ein Fragezeichen als letztes Zeichen bei einem Methodennamen – wie zum Beispiel bei r.checked?
bedeutet, daß die Methode einen boolschen Wert (true
oder false
) zurückliefert, ein Ausrufezeichen – wie bei @list.map!
weist darauf hin, daß die Methode destruktiv ist, daß sie also die Veränderungen am Original und nicht an einer Kopie vornimmt. Es gibt noch mehr dieser Konventionen, sie sind jedoch Konventionen und werden von Ruby nicht erzwungen.
Ein nachgestelltes if
wie beispielsweise in
alert selected.join if not selected.empty?
bedeutet, daß die Anweisung nur ausgeführt wird, wenn die if
-Bedingung true
ergibt. So verhindere ich, daß Shoes eine leere Alert-Box zurückgibt, wenn beim Aufruf des Programms noch kein Radiobutton angeklickt, aber dennoch das Auswahlknöpfchen gedrückt wurde.
Und selected
ist nach der Zuweisung erst einmal eine (einelementige) Liste, da durch die Methode .compact
alle leeren (nil
) Elemente entfert wurden, aber es ist und bleibt eine Liste. Erst die Methode .join
erzeugt dann daraus einen String. Der Methode .join
kann auch noch ein Trennzeichen mitgegeben werden, das die Listenelemente trennt, zum Beispiel ein Komma, aber da ich hier sicher wußte, daß die Liste nur einelementig ist, habe ich darauf verzichtet. Doch im nächsten Beispiel bei den Checkboxen, wird dieses Leerzeichen gebraucht.
Checkboxen ähneln Radiobutton, nur daß man eben mehrere von Ihnen ankreuzen kann. Dadurch sind sie etwas leichter zu implementieren und etwas schwieriger auszuwerten, da man ja Rücksicht darauf nehmen muß, daß mehrere Elemente zurückgegeben werden können. Ich habe das obige Beispiel dafür einfach ein wenig umgebaut um diesen Screenshot zu erhalten:
Schaut Ihr Euch das dazugehörende Skript an, werdet Ihr feststellen, daß die Änderungen gegenüber dem obigen Radiobutton-Beispiel wirklich minimal sind (wenn Ihr einmal davon abseht, daß ich die Wanderungen jetzt ebenfalls aufgenommen habe):
# encoding: utf-8
Shoes.app do
@list = ["Spaziergang nach Syrakus", "Die italienische Reise", "Ein Pyrenäenbuch", "Wanderungen durch die Mark Brandenburg"]
para "Welche dieser Klassiker der Reiseliteratur hast Du gelesen?"
stack do
@list.map! do |name|
flow {@c = check; para name}
[@c, name]
end
button "Deine Auswahl?" do
selected = @list.map {|c, name| name if c.checked?}.compact
alert selected.join(", ") if not selected.empty?
end
end
end
Lediglich check
für Checkboxen statt radio
für Radiobutton wurde geändert und der Gruppen-Identifier :books
konnte ebenfalls entfallen. Und dann habe ich, wie oben schon erwähnt, der Methode selected.join(", ")
ein Komma mit nachfolgendem Leerzeichen als Trenner für die einzelnen Listenelemente mitgegeben. Das funktioniert tatsächlich, wie gewünscht. Wählt einfach einmal nur ein Buch aus und Ihr werdet sehen: Kein überflüssiges Komma!
Damit sollte dieses Tutorial zu den Widgets eigentlich zu Ende sein. Zwar hatte ich bei der Vorstellung des Fortschrittsbalken im ersten Teil des Tutorials gedacht »Schade, daß es in Shoes keinen Slider gibt«, aber ich hatte nicht damit gerechnet, daß nach dem letzten Update mein Wunsch erfüllt wurde. Als ich nach diesem Update nämlich die Dokumentation durchstöberte, entdeckte ich, daß in den aktuellen Versionen 3.2 für MacOS X (Federales) respektive 3.3 (Walkabout) für den Rest der Welt ein Slider zu den fertigen Widgets hinzugefügt wurde. Wer also ein aktuelles Shoes sein eigen nennt, kann also auch einen Slider programmieren. Nutzer älterer Betriebssysteme, auf denen »nur« Shoes 3.1 (Policeman) läuft (wie mein alter Desktop mit MacOS X 10.6.8 Snow Leopard) müssen leider außen vor bleiben.
Im einfachsten Fall sieht ein Script für einen Slider (siehe Screenshot oben) so aus:
# encoding: utf-8
Shoes.app do
stack margin: 10 do
flow do
@sl = slider fraction: 0.50 do |sd|
@p.text = "Wert: #{(sd.fraction)}"
end
@p = para "", margin_left: 10
end
end
end
Wenn Ihr damit rumspielt, werdet Ihr sehen, daß der Slider einen einen Wert zwischen 0 und 1 zurückgibt. Ähnlich wie beim Fortschrittsbalken könnt Ihr mit fraction
den Startwert setzen (zwischen 0.0 und 1.0) und mit fraction()
den aktuellen Wert des Sliders erfragen.
Der Slider ist so aktuell, daß ich auch noch nicht viel mehr damit angestellt habe. Still digging!
Damit sind die Widgets, die Shoes erzeugt, abgehakt. In weiteren Tutorials möchte ich auf Texte und Graphiken und wie man diese mit Shoes erzeugt, eingehen. Bleibt mir also treu …
Über …
Der Schockwellenreiter ist seit dem 24. April 2000 das Weblog digitale Kritzelheft von Jörg Kantel (Neuköllner, EDV-Leiter, Autor, Netzaktivist und Hundesportler — Reihenfolge rein zufällig). Hier steht, was mir gefällt. Wem es nicht gefällt, der braucht ja nicht mitzulesen. Wer aber mitliest, ist herzlich willkommen und eingeladen, mitzudiskutieren!
Alle eigenen Inhalte des Schockwellenreiters stehen unter einer Creative-Commons-Lizenz, jedoch können fremde Inhalte (speziell Videos, Photos und sonstige Bilder) unter einer anderen Lizenz stehen.
Der Besuch dieser Webseite wird aktuell von der Piwik Webanalyse erfaßt. Hier können Sie der Erfassung widersprechen.
Diese Seite verwendet keine Cookies. Warum auch? Was allerdings die iframes
von Amazon, YouTube und Co. machen, entzieht sich meiner Kenntnis.
Werbung