II. Beispiel: Interaktion mit Buttons

  • Ziel des Beispiels:
  • Programm, welches einen vorgegebenen String auf Knopfdruck ausgibt

    1. Starten von FLUID.
    2. Anlegen der "int main()"-Methode durch New -> Code -> function/method. In der Eingabemaske müssen beide Zeilen gelöscht werden, dadurch legt FLUID die main()-Methode an.
    3. Inerhalb der main()-Methode wird nun über New -> Group -> Window ein Fenster angelegt. Dies wird das Hauptfenster unserer Applikation. Durch einen Doppelklick auf das Window-Element in der FLUID-Hierachie (FLUID-Hauptfenster) kann man das Eigenschaften-Menü öffnen und unter "Label" in der Registrierkarte "Style" einen Fensternamen für das Hauptfenster festlegen.
    4. Als nächstes wird ein Button gebraucht, diesen legen wir über New -> Buttons -> Button an. Ein Button erfordert ein paar Einstellungen im Eigenschaftenmenü. In der Registrierkarte "C++" muss im Textfeld "Callback" die Callback-Funktion angegeben werden, die beim Klick auf den Button ausgeführt werden soll. Hier wird einfach nur der Funktionsname ohne Klammern oder Semikolon eingegeben, in unserem Beispiel "Button_CB".
      Unter "GUI / Label" kann dem Button ein Schriftzug verpasst werden, der dann auf dem Buttons prangt.
    5. Anschließend muss die Callback-Methode des Buttons "Button_CB" angelegt werden. Dies geschieht über New -> Code -> Method/ Function.
      Name(args): (blank for main()):
      Hier muss der Name unserer im Button angegebenen Callback-Funktion eingetragen werden, also "Button_CB". Dahinter werden als Parameter ein FLTK-Objekt und eventuelle Daten (im Moment noch uninteressant) übergeben. In unserem Beispiel heißt der komplette Funktionsname "Button_CB(Fl_Widget*,void*)".
      Achtung: Es dürfen keine Leerzeichen enthalten sein und es wird zwischen Groß- und Kleinschreibung unterschieden.

      Return Type:
      Eine Callback-Funktion hat - zumindest in meinen Beispielen - keinen Rückgabetyp, da alle Auswertungen innerhalb der Funktion und des Hauptfenster ausgeführt werden. Nach FLTK-Vorgaben muss die Funktion trotzdem als statisch deklariert werden.
      In unserem Beispiel - wie bei auch bei den meisten Callback-Funktion später auch - muss "static void" eingeben werden.

    6. Als nächstes brauchen wir den Befehl zur Ausgabe auf der Konsole. Dazu markiert man im FLUID-Hauptfenster die Callback-Funktion des Buttons und fügt mit New -> Code -> Code ein Stück frei programmierbaren Code ein. Über einen Doppelklick öffnet sich der Code-Schnipsel zur Bearbeitung.
      Der bereits vorhandene Eintrag kann gelöscht werden und kann durch beliebigen Code ersetzt werden. Wir benötigen aber die ganz normale Ausgabe-Funktion, also trägt man
      			std::cout<<"How are you?"<<std::endl;
      		

      ein.
      Achtung: Hier muss korrekter C++-Code stehen, d.h., es muss an alle Semikolons und korrekte Namen gedacht werden. Zur besseren Lesbarkeit empfiehlt es sich später bei komplexeren Code-Fragmenten den Text mit Hilfe der Tabulator-Taste zu strukturieren, Stichwort: Bedingungen und Schleifen.

    7. Eines der Knackpunkte von FLUID ist die C-synchrone Hierachie. In einem C/C++-Programm, das in einer Datei realisiert wird, gibt es immer den Aufbau:
      • Klasseneinbindung (#include <...>)
      • Funktionen und Methoden (in unserem Beispiel bisher nur die Button_CB)
      • "int main()"-Methode
      Bis das Programm bei er Abarbeitung zur main()-Methode gelangt, müssen alle später benötigten Klassen und Methoden initialisiert worden sein, FLUID behandelt das ganze sehr ähnlich.
      Im Hauptfenster von FLUID kann man den Programmaufbau in einer Hierachie sehen und auch hier gilt, dass die Klassen über den Funktionen und über der main()-Methode stehen. Unsere "Button_CB"-Funktion steht noch unterhalb der "main()"-Methode. Wenn man im FLUID-Hauptfenster ein Element markiert, kann man es mittels F2 nach oben bzw. mittels F3 nach unten verschieben.
      Auf diese Weise kann man eine C/C++-synchrone Hierachie erstellen.
    8. Nun steht die Callback-Funktion unseres Buttons über der "main()"-Methode, aber etwas fehlt noch.
      Innerhalb des Code-Fragmentes in der Callback-Funktion benutzen wir den "std::cout"-Befehl, für den die Klasse "iostream" notwendig ist und genau diese muss noch eingebunden werden.
      Über New -> Code -> Code Declaration kann eine Zeile Code eingegeben werden, welche für
      			#include <iostream>
      		

      völlig ausreicht. Nicht vergessen, dass die Klasseninitialisierung am Anfang des Programms stehen muss und mittels F2 nach oben verschoben werden kann.
    9. Damit dürfte unser erstes Beispiel-Programm, welches auf Knopfdruck "How are you?" auf der Linux-Kommando-Zeile bzw. in der MySys-Umgebung unter Windows ausgibt, fertig sein.

      Achtung: Die meisten Makefiles greifen auf .CPP-Dateien zurück, FLUID schreibt standardmäßig .CXX-Dateien. Um dies zu ändern muss über Edit -> Project Settings das cxx durch ein cpp ersetzt werden.

      Jetzt noch unter File -> Write Code die CPP-Dateien erzeugen und wie gehabt kompilieren und ausführen.

      Achtung: Es empfiehlt sich das FL-Projekt hin und wieder zu speichern, weil FLUID gelegentlich auch mal astürtzt und nicht automatisch speichert. Leider kann FLUID aus einer mit FLUID-erstellten C++-Datei kein Projekt rekonstruieren.

    10. Hinweis: Einer der großen Vorteile von FLUID bestehen darin, dass es möglich ist, die ganze Ausrichtung von grafischen Elementen in der Vorschau schon einzustellen, in dem man die Elemente einfach in ihrer Größe oder Position "durch Ziehen" verändert. Dies erspart einem das Jonglieren mit Pixeln für Größe und Position.
    11. Tutorial-2-1.fl Tutorial-2-1.h Tutorial-2-1.cpp

    Ein Programm, welches den Inhalt eines Ausgabefeldes auf Knopfdruck ändert

    1. Die Schritte 1 bis 5 wiederholen sich an dieser Stelle:
    2. Als nächstes brauchen wir im Hauptfenster ein entsprechenden Ausgabe-Feld. Man marktiert das "Window"-Element innerhalb der main()-Methode und legt über New -> Text -> Output ein neues Ausgabefeld an, diese Felder sind - wie der Name schon sagt - ausschließlich für die Ausgabe bestimmt.
    3. Anschließend ruft man das Eigenschaften-Menü auf und hier kommt wieder einer der Kanckpunkte in FLUID.
      Zum einen kann man unter "GUI / Label" (Registrierkarten) den Text vor dem eigentlichen Ausgabefeld bestimmen und zum anderen - was viel wichtiger ist - muss man unter der Registrierkarte "C++" im Feld "Name" etwas eitragen, bei mir "output". An dieser Stelle wird ein Pointer auf das Ausgabefeld angelegt mit dessen Hilfe später das Ausgabe-Feld verändert werden kann.
    4. Nun geht es weiter in der CallBack-Funktion des Buttons, "Button_CB". Hier muss nun ein Befehl eingegeben werden, der den Inhalt des Ausgabefeldes "output" manipuliert.
      Wieder wird über New -> Code -> Code ein Quelltext-Schnippsel innerhalb der CallBack-Funktion eingefügt. Diesmal ändert sich der Befehl innerhalb des Code-Stückchens in
      			output->value("How are your?");
      		

      dabei ist output der Pointer auf das Ausgabefeld und value ein Pointer auf dessen Wert.
      Allgemein kann man sagen, dass Ausgabewerte (auch wenn sie in einem Eingabefeld dargestellt werden), vom Typ const char* sein müssen.
    5. Noch Kompilieren und Ausgeben, das war's schon.
    6. Tutorial-2-2.fl Tutorial-2-2.h Tutorial-2-2.cpp

    Ein Programm, welches auf Knopfdruck den Inhalt eines Eingabe ausliest und anschließend als Konsolenbefehl ausführt

    1. Die Schritte 1 bis 5 wiederholen sich an dieser Stelle:
    2. Es wird jetzt anstatt einem Ausgabefeld ein Eingabefeld benötigt. Also legen wir im "Window"-Element der main()-Methode über New -> Text -> Input ein entsprechendes Eingabefeld an.
    3. Im Eigenschaftenmenü muss wieder ein Pointername vergeben werden, in meinem Beispiel soll er einfach nur "input" heißen.
      In "GUI / Label" kann wieder ein entsprechender Text eingegeben werden.
    4. Als nächstes muss die Callback-Methode des Buttons bearbeitet werden und wie in den Beispielen zuvor, muss der über New -> Code -> Code ein Code-Fragment eingefügt werden.
      Der Befehl ändert sich diesmal in:
      			system(input->value());
      		

      Im einzelnen bedeutet dass:
    5. Damit der system-Befehl genutzt werden kann, muss die stdlib.h mit eingebunden werden.
      Dies geschieht wie schon im ersten Beispiel über New -> Code -> Declaration. Dann einfach noch in die Zeile
      			#include
      		

      eingeben und das Programm ist fertig.
    6. Es folgt das Kompilieren und Ausführen, zum Testen sollte man anfangs harmlosere Konsolenbefehle wie "dir" ausprobieren.
    7. Tutorial-2-3.fl Tutorial-2-3.h Tutorial-2-3.cpp