image image


Keiner kennt Shoes: Widgets (2)

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

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:

image

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:

image

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

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:

image

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!

Slider

image

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 …


Noch mehr Shoes-Tutorials im Schockwellenreiter


image


(Kommentieren)  Keiner kennt Shoes: Widgets (2) – 20151124 bitte flattrn

image image



Ü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


Werbung


image  image  image
image  image  image