Tutorial
Einführung in die GUI-Programierung mit FLTK
von Lothar Schirm | Seite 1 von 1 |
(Siehe auch: Englisches Tutorial / English tutorial: Introduction to GUI Programming with FLTK [EN])
Inhalt
1. Was ist FLTK?
2. Download und Installation
3. Ein erstes Programm
4. Widgets
4.1 Fl_Button
4.2 Fl_Input und Fl_Output
4.3 Fl_Text_Editor und Fl_Text_Display
4.4 Fl_Browser
4.4.1 Eine Listbox
4.4.2 Eine Tabelle in einen Browser schreiben
4.5 Fl_Chart
4.6 Fl_Choice
4.7 Fl_Menu_Bar, flFileChooser, flMessageBox
4.8 Weitere Standarddialoge (Common dialogs)
1. Was ist FLTK?
FLTK (Fast Light Toolkit) ist eine leicht zu handhabende C++ GUI-Bibliothek für
Linux und Windows. Siehe Homepage http://www.fltk.org. Es gibt hierzu auch einen Wrapper für FreeBasic im englischen FreeBasic-Forum. Hier die Projektseite:
"FLTK C for FreeBasic" von D.J.Peters
(http://www.freebasic.net/forum/viewtopic.php?f=14&t=24547)
Dort ist auch ein Link für den Download der Dokumentation angegeben. Im Download des Wrappers sind zahlreiche Codebeispiele enthalten, die die Einarbeitung sehr erleichtern.
Außer grafischen Benutzeroberflächen lassen sich auch Grafiken mit entsprechenden
Zeichenbefehlen erzeugen. Ebenso kann OpenGL verwendet werden. Grafikprogrammierung mit FLTK ist jedoch nicht Gegenstand dieses Tutorials. Hierzu möchte ich auf die Codebeispiele im Wrapper verweisen.
Es gibt zu FLTK auch einen GUI-Designer (FLUID). Dieser erzeugt jedoch C++ Code,
so dass er für FreeBasic nicht verwendet werden kann.
2. Download und Installation
Siehe Beschreibung auf der Projektseite.
3. Ein erstes Programm
Wir beginnen mit einem einfachen Programm: Ein Fenster mit einem Text ("Willkomen bei FLTK!") und einem Button. Wenn der Button gedrückt wird, soll auf das Konsolenfenster eine Testausgabe erfolgen: "Button wurde gedrückt!"
Der Code hierzu ist sehr einfach:
#Include "fltk-c.bi"
'Fenster und Widgets:
Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Box Ptr Box_text
Dim Shared As Fl_Button Ptr Button_Click
Sub Create_Window_Main()
'Fenster mit Button:
Window_Main = Fl_WindowNew(300, 200, "Button-Test")
Box_text = Fl_BoxNew (100, 80, 100, 20, "Willkommen bei FLTK!")
Button_Click = Fl_ButtonNew(100, 160, 100, 20, "Click me!")
End Sub
Sub Button_Click_Event Cdecl (widget As FL_Widget Ptr)
'Callback-Funktion für Button
Print "Button wurde gedrueckt!"
End Sub
'Hauptprogramm:
Create_Window_Main()
Fl_WidgetSetCallback0(Button_Click, @Button_Click_Event)
Fl_WindowShow(Window_Main)
Fl_Run
End
Hier ein Screenshot:
Nun zum Code: Was heißt das alles?
In der ersten Zeile binden wir die Headerdatei fltk-c.bi ein.
Danach kommt die Definition des Fensters mit seinen Elementen (Boxen, Buttons,
darüber hinaus auch Texteingabefelder usw.). Alle diese Elemente werden in FLTK
als Widgets bezeichnet. In FLTK werden alle Fenster und die Widgets als Pointer
übergeben, ebenso Strings (als ZString Pointer), siehe Beispiele ab 4.2.
Ich habe mir angewöhnt, die Definition für jedes Fenster in einer eigenen Sub
zu verpacken, obwohl das nicht zwingend notwendig ist. In den kleinen
Beispielprogrammen des Wrappers ist dies generell nicht der Fall. Es steigert
aber meines Erachtens die Übersichtlichkeit des Codes, insbesondere bei größeren
Projekten mit mehreren Fenstern. Man kann dann auch mit dem Function-Browser
der IDE leicht die Fensterdefinitionen wiederfinden.
Im Code haben wir für den Text ein Widget Fl_Box verwendet. Dies ist einfach
ein rechteckiger Bereich mit einem Text.
Nennen wir das Fenster "Window_Main", die Box "Box_text" und den Button "Button_Click". Diese werden mit "Dim Shared" als globale Variablen vom Typ FL_Window Ptr, Fl_Box Ptr bzw. Fl_Button Ptr deklariert, so dass wir in den Callback-Funktionen (siehe unten) auf diese zugreifen können. Beispiele zu Callback-Funktionen folgen in diesem Tutorial.
Die Fensterdefinition für unser Fenster "Window_Main" erfolgt in einer Sub, die wir
"Create_Window_Main" nennen. Innerhalb der Sub benötigen wir drei Funktionen:
Function Fl_WindowNew(w as integer, h as integer, title as const zstring ptr = 0) as Fl_Window ptr
Function Fl_BoxNew(x as integer, y as integer, w as integer, h as integer, label as const zstring ptr=0) as Fl_Box ptr
Function Fl_ButtonNew(x as integer, y as integer, w as integer, h as integer, label as const zstring ptr = 0) as Fl_Button ptr
Die Parameterübergabe, wie in den Funktionen "Fl_BoxNew" oder "Fl_ButtonNew",
ist für alle Widgets immer die selbe:
Name des Widgets
x, y = Position der linken oberen Ecke des Widgets (Pixelkoordinaten)
w = Breite des Widgets in Pixeln
h = Höhe des Widgets in Pixeln
label = Beschriftung.
Beispiele für andere Widgets folgen unten.
Nach der Sub "Create_Window_Main" kommt unsere Callback-Funktion für den
Button_Click. Wir nennen sie Button_Click_Event. Wichtig ist das Cdecl und der
Übergabeparameter vom Typ Fl_Widget Ptr. In die Callback-Funktion schreiben wir rein, was unser Programm tun soll, wenn der Button_Click gedrückt wird.
Das Hauptprogramm ist dann sehr kurz. Zunächst wird unsere Sub "Create_Window_Main" aufgerufen. Dann erfolgt mit Fl_WidgetSetCallback0 die Verknüpfung des Buttons "Button_Click" mit der Callback-Funktion. Mit Fl_WindowShow zaubern wir unser Fenster auf den Bidschirm. Bei Programmen mit mehreren Fenstern ist Fl_WindowHide von Nutzen, damit können wir ein Fenster wieder vom Bildschirm verschwinden lassen. Mit Fl_Run läuft das Programm, bis das Fenster über den Schließen-Button in der Titelleiste oder über das Kontextmenü des Fensters in der Taskleiste geschlossen wird.
Fl_WidgetSetCallback0 sieht wegen der Null am Ende etwas seltsam aus, das ist
aber kein Druckfehler. Es gibt in FLTK nämlich die Möglichkeit, verschiedene
Typen von Callback-Funktionen zu erzeugen. Man kann mit Fl_WidgetSetCallback1Arg, Fl_WidgetSetCallback oder Fl_WidgetSetCallbackArg an die Callback-Funktion in verschiedener Weise zusätzlich Parameter übergeben. Beispiele hierzu finden sich im Download des Wrappers so wie auch in diesem Tutorial.
Das obige Programm muss natürlich wegen der Print-Anweisung in der Callback-
Funktion als Konsolenprogramm compiliert werden. Das gilt auch für die nachfolgenden Beispiele, soweit sie den Print-Befehl beinhalten.
Zusätzlich zum FLTK-GUI können wir auch mit "ScreenRes" das normale Grafikfenster
öffnen und mit den normalen FreeBasic-Befehlen hier unsere Grafiken erzeugen.
Das ist das schöne an GUI-Bibliotheken wie FLTK, GTK+, WX-C u.a: Wir können nach wie vor das Konsolenfenster (vorzugsweise für Testausgaben/zum Debuggen) und das Grafikfenster in der gewohnten Weise benutzen, bekommen aber ein GUI gratis dazu.
4. Widgets
FLTK stellt verschiedenen Klassen von Widgets zur Verfügung.
Die Klasse Fl_Button unterstützt verschiedene Arten von Buttons, z.B. normale
Buttons (siehe oben), Togglebuttons, Checkbuttons, Radiobuttons u.a.
Die Widgets Fl_Input, Fl_Output, Fl_Text_Editor, Fl_Text_Display und Fl_Help_View ermöglichen Ein- und Ausgabe von Text in einfacher oder auch anspruchsvollerer Form.
Die Klasse Fl_Valuator beinhaltet z.B. Scrollbars (Fl_Scrollbar) und Sliders (Fl_Slider).
Die Klasse Fl_Menu_ ermöglicht die Erstellung von Menüs (Fl_Menu_Bar) und beinhaltet auch Comboboxen (Fl_Choice).
Die Klasse Fl_Browser_ ermöglicht die Darstellung von Listen und Tabellen sowie
die Erstellung von Listboxen mit Einfach- oder Mehrfachauswahl.
Benutzeroberflächen können z.B. durch Scrollaereas (Fl_Scroll), Tabs (Fl_Tabs) oder Tiles (Fl_Tile) übersichtlich strukturiert werden.
FLTK stellt auch Standarddialoge (common dialogs) zur Verfügung, z.B. Messageboxen, Inputboxen, Dateiauswahl oder Farbauswahl.
Im Rahmen dieses Tutorials kann nicht auf alle diese Widgets eingegangen werden.
Die wichtigsten werden im folgenden erklärt und ihre Verwendung mit ein paar kleinen
Anwendungsbeispielen gezeigt. Für weitere Einzelheiten wird auf die Codebeispiele
im Download hingewiesen sowie auf die Dokumentation und die Header-Datei fltk-c.bi.
4.1 Fl_Button
Die Klasse Fl_Button umfasst folgende Widgets:
Fl_Light_Button: aktiviert ein "Licht" (kleines Quadrat links im Button, wenn er angeklickt wird. Der Fl_Check_Button ist eine Unterklasse davon
Fl_Radio_Button: Radiobutton (Option Button)
Fl_Repeat_Button: erzeugt fortlaufende Callbacks, so lange er gedrückt wird
Fl_Return_Button: reagiert auf Mausklick oder auf die Return-Taste (Enter-Taste)
Fl_Toggle_Button: Togglebutton
Beispiel für einen einfachen Button siehe oben.
Hier ein Beispiel für Fl_Toggle_Button, Fl_Radio_Round_Button und Fl_Check_Button (ein Fl_Radio_Round_Button hat links einen Kreis, der den "aktiven" Zustand des Buttons mit einer Markierung anzeigt, während der einfache Fl_Radio_Button nur wie ein Togglebutton funktioniert):
#Include "fltk-c.bi"
'Widgets
Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Toggle_Button Ptr Button_toggle
Dim Shared As Fl_Group Ptr Group_radio
Dim Shared As Fl_Radio_Round_Button Ptr Button_radio_red, Button_radio_yellow, Button_radio_green
Dim Shared As Fl_Check_Button Ptr Button_check
Dim Shared As Fl_Button Ptr Button_close
Sub Create_Window_Main()
'Hauptfenster mit Buttons
Window_Main = Fl_WindowNew(200, 250, "Test Buttons")
Button_toggle = Fl_Toggle_ButtonNew(20, 20, 100, 20, "Togglebutton")
Group_radio = Fl_GroupNew(10, 70, 120, 90, "Wähle eine Farbe:")
Fl_GroupBegin(Group_radio)
Button_radio_red = Fl_Radio_Round_ButtonNew(20, 80, 100, 20, "rot")
Button_radio_yellow = Fl_Radio_Round_ButtonNew(20, 110, 100, 20, "gelb")
Button_radio_green = Fl_Radio_Round_ButtonNew(20, 140, 100, 20, "grün")
Fl_GroupEnd(Group_radio)
Button_check = Fl_Check_ButtonNew(20, 170, 100, 20, "Checkbutton")
Button_close = Fl_ButtonNew(20, 200, 100, 20, "Beenden")
End Sub
Sub Buttons_Event Cdecl (widget As Fl_Widget Ptr, arg As Any Ptr)
'Callbackfunktion für alle Buttons
Select Case arg
Case Button_toggle
Print Fl_ButtonGetValue(Button_toggle)
Case Button_radio_red
Print "rot"
Case Button_radio_yellow
Print "gelb"
Case Button_radio_green
Print "grün"
Case Button_check
Print Fl_ButtonGetValue(Button_check)
Case Button_close
End
End Select
End Sub
'Hauptprogramm:
Create_Window_Main()
Fl_WidgetSetCallbackArg(Button_toggle, @Buttons_event(), Button_toggle)
Fl_WidgetSetCallbackArg(Button_radio_red, @Buttons_event(), Button_radio_red)
Fl_WidgetSetCallbackArg(Button_radio_yellow, @Buttons_event(), Button_radio_yellow)
Fl_WidgetSetCallbackArg(Button_radio_green, @Buttons_event(), Button_radio_green)
Fl_WidgetSetCallbackArg(Button_check, @Buttons_event(), Button_check)
Fl_WidgetSetCallbackArg(Button_close, @Buttons_event(), Button_close)
Fl_WindowShow(Window_Main)
Fl_Run
End
Hier der Screenshot des laufenden Programms:
Wir haben jetzt also einen Togglebutton, drei Radiobuttons, einen Checkbutton und einen Button zum Schließen des Fensters und Beenden des Programms. Die drei Radiobuttons müssen wir in einer Gruppe zusammenschließen, da es sich hier um eine Auswahl "eins aus drei" handeln soll. Das geschieht mit Hilfe eines Widgets Fl_Group und den Befehlen Fl_GroupBegin und Fl_GroupEnd.
Jetzt könnten wir wie im Einführungsbeispiel für jeden Button eine eigene Callbackfunktion schreiben. Wir wollen uns aber das Leben vereinfachen und nur eine Callbackfunktion für alle sechs Buttons schreiben. Das geht mit Fl_WidgetSetCallbackArg statt Fl_WidgetSetCallback0, denn hier können wir zusätzlich einen Pointer an die Callbackfunktion übergeben, z.B. einen Pointer auf das betreffende Widget. Dann können wir in die Callbackfunktion für jedes in Frage kommende Widget hineinschreiben, was passieren soll. Den Zustand eines Buttons (1 oder 0) können wir mit Fl_ButtonGetValue abfragen (siehe im Beispiel beim Togglebutton oder beim Checkbutton). Bei den Radiobuttons ist es anders gemacht, aber auch dort könnte man Fl_ButtonGetValue verwenden. Beim normalen Button (Fl_Button) macht das natürlich wenig Sinn.
4.2 Fl_Input und Fl_Output
Das Widget Fl_Input ist ein einzahliges Texteingabefeld mit einer Eingabeaufforderung, so ein bisschen wie der Befehl "Input" in FreeBasic. Das Widget Fl_Output sieht genau so aus, kann aber nur Text darstellen. Es gibt auch Ein- und Ausgabefelder für mehrzeilige Texte (Fl_Multiline_Input und Fl_Multiline_Output).
Beispiel: ein Programm mit einem Fl_Input und einem Fl_Output sowie einem Button. Durch Drücken des Buttons soll der Text aus dem Fl_Input in das Fl_Output kopiert werden.
#Include "fltk-c.bi"
'Fenster und Widgets:
Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Input Ptr Input_text
Dim Shared As Fl_Output Ptr Output_text
Dim Shared As Fl_Button Ptr Button_Copy
Sub Create_Window_Main()
'Fenster mit Widgets:
Window_Main = Fl_WindowNew(300, 200, "Button-Test")
Input_text = Fl_InputNew(100, 50, 180, 20, "Texteingabe:")
Output_text = Fl_OutputNew(100, 80, 180, 20, "Textausgabe:")
Button_Copy = Fl_ButtonNew(100, 150, 100, 20, "Kopieren")
Fl_Input_SetValue(Input_text, "Editiere mich!")
End Sub
Sub Button_Copy_Event Cdecl (widget As FL_Widget Ptr)
'Callback-Funktion für Button
Dim As String text
text = *Fl_Input_GetValue(Input_text)
Fl_Input_SetValue(Output_text, text)
End Sub
'Hauptprogramm:
Create_Window_Main()
Fl_WidgetSetCallback0(Button_Copy, @Button_Copy_Event)
Fl_WindowShow(Window_Main)
Fl_Run
End
Lassen wir das Programm laufen, erhalten wir folgendes Bild:
Wir können den Text "Editiere mich!" verändern und mit Drücken des Buttons
"Kopieren" in das Textausgabefeld kopieren.
Nun zum Code. Dieser ist eine Erweiterung des einführenden Beispiels. Der "Button_Click" wurde in "Button_Copy" umbenannt. In die Deklaration der Widgets und in die Sub "Create_Window_Main" wurden die neuen Widgets mit den Namen "Input_text" und "Output_text" zusätzlich aufgenommen. Die Syntax ist eigentlich selbsterklärend. Mit Fl_Input_SetValue wurde das Texteingabefeld mit einem editierbaren Text vorbelegt.
Nun zur Callback-Funktion. Mit "text = *Fl_Input_GetValue(Input_text)" wird der
Text aus dem Eingabefeld Input_text ausgelesen. Man beachte das Sternchen! Die Funktion Fl_Input_GetValue liefert nämlich nur einen Pointer auf einen ZString zurück. Mit dem Sternchen davor wird der Wert dieses ZString ausgegeben (Pointer-Dereferenzierung, siehe FB Referenz Stern). Mit Fl_Input_SetValue wird der Text in das Ausgabefeld eingetragen, obwohl es sich um ein Fl_Output Widget handelt. Einen Befehl "Fl_Output_SetValue" gibt es nicht, da Fl_Input in der Klassenhierarchie der Widgets oberhalb von Fl_Output angeordnet ist.
Die Klasse Fl_Input beinhaltet folgende Widgets:
Fl_File_Input: zeigt einen Pfadnamen in einem Texteingabefeld an
Fl_Float_Input: erlaubt nur die Eingabe von Gleitkommazahlen
Fl_Int_Input: erlaubt nur die Eingabe von Dezimalziffern
Fl_Secret_Input: zur verdeckten Passworteingabe, es werden nur Platzhalter angezeigt
Fl_Output: siehe oben
4.3 Fl_Text_Editor und Fl_Text_Display
Das Widget Fl_Text_Editor ist ein Widget zur Eingabe von Text, wobei der Text
vertikal und horizontal mit Scrollbalken gescrollt werden kann, falls die
Textdarstellung größer ist als das Texteingabefeld.
Auch hier wieder ein Codebeispiel:
#Include "fltk-c.bi"
'Fenster und Widgets:
Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Text_Editor Ptr Editor_text
Dim Shared As Fl_Text_Buffer Ptr Buffer_text
Dim Shared As Fl_Button Ptr Button_Copy
Sub Create_Window_Main()
'Fenster mit Widgets:
Window_Main = Fl_WindowNew(300, 300, "Editor-Test")
Editor_text = Fl_Text_EditorNew (10, 10, 280, 200)
Button_Copy = Fl_ButtonNew(100, 230, 100, 20, "Kopieren")
'Texteditor mit einem Text vorbelegen:
Buffer_text = Fl_Text_BufferNew()
Fl_Text_DisplaySetBuffer(Editor_text, Buffer_text)
Fl_Text_BufferSetText(Buffer_text, "Üb immer Treu und Redlichkeit bis an dein selig Ende")
End Sub
Sub Button_Copy_Event Cdecl (widget As FL_Widget Ptr)
'Callback-Funktion für Button
Dim As String text
text = *Fl_Text_BufferGetText(Buffer_text)
Print text
End Sub
'Hauptprogramm:
Create_Window_Main()
Fl_WidgetSetCallback0(Button_Copy, @Button_Copy_Event)
Fl_WindowShow(Window_Main)
Fl_Run
End
Das Programm erzeugt das folgende Fenster:
Der vorbelegte Text kann editiert werden. Wenn man auf den Button "Kopieren" drückt, wird der Text kopiert und auf das Konsolenfenster ausgegeben.
Im Code erscheint als neues Widget der Texteditor mit dem vorbelegten Text
"Üb immer Treu und Redlichkeit bis an dein selig Ende". Leider lässt sich das Widget
Fl_Text_Editor nicht direkt beschreiben, nur über einen Textbuffer, der als
Fl_Text_Buffer extra erzeugt und dem Texteditor zugeordnet werden muss. Dies
geschieht mit Hilfe der Funktionen Fl_Text_BufferNew und Fl_Text_DisplaySetBuffer ("Fl_Text_EditorSetBuffer" gibt es nicht - Stichwort "Klassenhierarchie der Widgets", siehe oben). Dann kann der Textbuffer mit Fl_Text_BufferSetText beschrieben oder mit Fl_Text_BufferGetText ausgelesen werden (Sternchen: Pointer-Dereferenzierung, siehe oben).
Wenn man nur Text anzeigen will, ohne dass er geändert werden soll, verwendet man
das Widget Fl_Text_Display. Die Syntax zur Deklaration (Fl_Text_DisplayNew anstatt Fl_Text_EditorNew), Erstellung des Textbuffers und Beschreiben sowie Auslesen des Textbuffers entspricht völlig der beim Fl_Text_Editor.
Will man Text mit Zeilenumbruch in einen Textbuffer schreiben, so setzt man an
die Stellen des Zeilenumbruchs Chr(10) ein:
Fl_Text_BufferSetText(Buffer_text, "Ich ging im Wald so für mich hin" + Chr(10) +_
"und nichts zu suchen, das war mein Sinn."
4.4 Fl_Browser
Ein Fl_Browser zeigt eine Liste von Strings an, die gescrollt werden kann. Zur Klasse Fl_Browser gehören folgende Widgets:
Fl_File_Browser: zeigt eine Liste von Dateinamen an, optional mit Icons
Fl_Hold_Browser: eine Listbox, aus der ein Eintrag ausgewählt werden kann,
wobei die Auswahl mit einem blauen Balken markiert bleibt, wenn die Maus losgelassen wird
Fl_Multi_Browser: eine Listbox mit Mehrfachauswahl
Fl_Select_Browser: eine Listbox, aus der ein Eintrag ausgewählt werden kann,
wobei die Auswahl nicht markiert bleibt, wenn die Maus losgelassen wird
4.4.1 Eine Listbox
Beispiel für eine Listbox mit einem Hold_Browser:
#Include "fltk-c.bi"
'Fenster und Widgets:
Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Hold_Browser Ptr Browser_Auswahl
Sub Create_Window_Main()
'Fenster mit Widgets:
Dim As Integer i
Window_Main = Fl_WindowNew(200, 200, "Hold_Browser")
Browser_Auswahl = Fl_Hold_BrowserNew(10, 10, 180, 160, "Listen-Auswahl")
For i = 1 To 20
Fl_BrowserAdd(Browser_Auswahl, "Eintrag Nr." + Str(i))
Next
End Sub
Sub Browser_Auswahl_Event Cdecl (widget As FL_Widget Ptr)
'Callback-Funktion für den Browser
Dim As Integer i
Dim As String text
i = Fl_BrowserGetValue(Browser_Auswahl)
text = *Fl_BrowserGetText(Browser_Auswahl, i)
Print i
Print text
End Sub
'Hauptprogramm:
Create_Window_Main()
Fl_WidgetSetCallback0(Browser_Auswahl, @Browser_Auswahl_Event)
Fl_WindowShow(Window_Main)
Fl_Run
End
Hier der zugehörige Screenshot, dieses mal mit Testausgabe auf das Konsolenfenster:
Wie man im Code sieht, werden dem Browser mit Fl_BrowerAdd zeilenweise die
Einträge zugefügt. Falls wir den Browser neu beschreiben wollen, können wir seinen
Inhalt mit Fl_BrowerClear löschen. Beispiel:
Fl_BrowserClear(Browser_Auswahl)
Die Nummer des mit der Maus ausgewählten Eintrages können wir mit Fl_BrowserGetValue abfragen, und den zugehörigen Text mit Fl_BrowserGetText (siehe Callbackfunktion im Code).
4.4.2 Eine Tabelle in einen Browser schreiben
Einen Browser können wir grundsätzlich zur Erstellung beliebiger Listen und auch
Tabellen verwenden. Wenn wir eine Tabelle in den Browser schreiben wollen, müssen
wir vorher die Anzahl der Spalten und deren Breite (in Pixeln) festlegen. Das geht
mit Fl_BrowserSetColumnWidths. Diese Sub ist wie folgt definiert:
Sub Fl_BrowserSetColumnWidths(br As Fl_Browser Ptr, arr As Const Integer Ptr)
br ist der Pointer auf den Browser. arr ist ein Pointer auf ein Array, dessen
Elemente die Spaltenbreiten angeben. Das Array muss nullterminiert sein, dass heißt,
das letzte Element muss 0 sein! Außerdem muss es vom Typ "Const Integer" sein,
also global deklariert.
Die Einträge in den Browser erfolgen in der schon bekannten Weise mit Fl_BrowerAdd, wobei die Spalten durch Chr(9) getrennt werden. Wir können mit Fl_BrowserSetColumnChar auch andere Trennzeichen wählen:
Sub Fl_BrowserSetColumnChar(br as Fl_Browser ptr, c as ubyte)
Für c müssen wir den ASCII-Code des gewünschten Zeichens einfügen. Das ist sehr
praktisch, wenn wir z.B. eine mit Excel erzeugte CSV-Datei darstellen wollen,
dann setzen wir für c Asc(";") ein.
Hier als Beispielcode eine Funktionstabelle:
#Include "fltk-c.bi"
Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Browser Ptr Browser_Tabelle
Dim Shared As Integer col(3) = {80, 80, 80, 0}
Dim As Single x
Sub CreateWindow_Main
'Fenster mit Widgets:
Window_Main = Fl_WindowNew(300, 300, "Tabelle")
Browser_Tabelle = Fl_BrowserNew(10, 10, 280, 280)
Fl_BrowserSetColumnWidths(Browser_Tabelle, @col(0))
End Sub
'Hauptprogramm
CreateWindow_Main()
Fl_WindowShow(Window_Main)
'Funktionstabelle für x^2 und Sqr(x) schreiben:
Fl_BrowserAdd(Browser_Tabelle, "x" + Chr(9) + "x^2" + Chr(9) + "Sqr(x)")
For x = 0 To 100
Fl_BrowserAdd(Browser_Tabelle, Str(x) + Chr(9) + Str(x^2) + Chr(9) + Str(Sqr(x)))
Next
Fl_Run
End
Hier der Screenshot:
4.5 Fl_Chart
Da wir gerade bei Funktionstabellen sind: Man kann mit Fl_Chart auch
Funktionsverläufe grafisch einfach darstellen oder sonstige einfache Diagramme.
Beispiel: Eine Sinuskurve
#Include "fltk-c.bi"
Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Chart Ptr Chart_Sinus
Dim As Integer i
Dim As Single x, dx
Const Pi = 4 * Atn(1)
Sub CreateWindow_Main()
'Fenster mit Diagramm
Window_Main = Fl_WindowNew(400, 240, "Chart")
Chart_Sinus = Fl_ChartNew (10, 10, 380, 200, "Zeitache = 4 * pi")
Fl_WidgetSetType(Chart_Sinus, FL_CHART_LINE)
End Sub
'Hauptprogramm
CreateWindow_Main()
Fl_WindowShow(Window_Main)
'Sinuskurve ins Diagramm eintragen:
dx = 4 * pi / 100
For i = 0 To 100
x = i * dx
Fl_ChartAdd(Chart_Sinus, Sin(x), "", FL_RED)
Next
Fl_Run
End
Screenshot:
Unser Widget nennen wir "Chart_Sinus" (siehe Code). Mit Fl_WidgetSetType können wir den Typ des Diagramms festlegen, z.B.:
FL_CHART_BAR: Balkendiagramm
FL_CHART_LINE: Liniendiagramm
FL_CHART_PIE: Kreisdiagramm (Tortendiagramm)
Mit Fl_ChartAdd werden nacheinder die darzustellenden Werte eingetragen. Der
zweite Parameter gibt den einzutragenden Zahlenwert ein, der dritte eine hierzu
gehörende Beschriftung (optional) und der letzte Wert die Farbe. Die Farbkonstanten
FL_RED, FL_GREEN, FL_BLUE usw. sind in der Headerdatei fltk-c.bi deklariert.
4.6 Fl_Choice
Das Widget Fl_Choice ist eine Combobox. Hier ein Beispiel:
#Include "fltk-c.bi"
Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Choice Ptr Choice_Liste
Sub Create_Window_Main()
'Hauptfenster
Dim As Integer i
Window_Main = Fl_WindowNew (200, 240, "Combobox")
Choice_Liste = Fl_ChoiceNew (60, 20, 120, 20, "Auswahl:")
For i = 0 To 10
Fl_Menu_Add(Choice_Liste, "Auswahl Nr. " + Str(i))
Next
Fl_ChoiceSetValue(Choice_Liste, 0)
End Sub
Sub Choice_Liste_Event Cdecl (widget As Fl_Widget Ptr)
'Callbackfunktion
Print Fl_ChoiceGetValue(Choice_Liste)
End Sub
'Hauptprogramm
Create_Window_Main()
Fl_WidgetSetCallback0(Choice_Liste, @Choice_Liste_Event)
Fl_WindowShow(Window_Main)
Fl_Run
End
Der zugehörige Screenshot:
Der Code ist so ähnlich wie beim Beispiel der Listbox. Da jedoch der Fl_Choice
eine Unterklasse von F-Menu_ ist, geschieht das Hinzufügen von Daten nicht mit "Fl_ChoiceAdd", sondern mit Fl_Menu_Add. Mit Fl_ChoiceSetValue wird der Index des zunächst im Fenster der Combobox anzuzeigenden Eintrages angegeben.
4.7 Fl_Menu_Bar, flFileChooser, flMessageBox
Mit Fl_Menu_Bar können wir ein klassiches Menü erzeugen. Beispiel:
#Include "fltk-c.bi"
'Deklaration der Callback-Funktionen - die kommen unten:
Declare Sub Neu Cdecl (widget As Fl_Widget Ptr, userdata As Any Ptr)
Declare Sub Oeffnen Cdecl (widget As Fl_Widget Ptr, userdata As Any Ptr)
Declare Sub Speichern Cdecl (widget As Fl_Widget Ptr, userdata As Any Ptr)
Declare Sub Beenden Cdecl (widget As Fl_Widget Ptr, userdata As Any Ptr)
Declare Sub Info Cdecl (widget As Fl_Widget Ptr, userdata As Any Ptr)
Dim Shared As Fl_Window Ptr Window_Main
Dim Shared As Fl_Menu_Bar Ptr Menu
Sub CreateWindow_Main()
'Fenster mit Menü
Window_Main = Fl_WindowNew (300, 200, "Menü-Test")
Menu = Fl_Menu_BarNew(0, 0, 300, 30)
Fl_Menu_Add(Menu, "Datei/Neu",, @Neu())
Fl_Menu_Add(Menu, "Datei/Öffnen",,@Oeffnen())
Fl_Menu_Add(Menu, "Datei/Speichern",,@Speichern())
Fl_Menu_Add(Menu, "Datei/Beenden",,@Beenden())
Fl_Menu_Add(Menu, "Hilfe/Info",,@Info())
End Sub
'Callback-Funktionen:
Sub Neu Cdecl (widget As Fl_Widget Ptr, userdata As Any Ptr)
Print "Neue Datei"
End Sub
Sub Oeffnen Cdecl (widget As Fl_Widget Ptr, userdata As Any Ptr)
'Eine Datei auswählen zum öffnen:
Dim As ZString Ptr file
file = flFileChooser("Datei öffnen", "*.bas" + Chr(9) + "*.txt", ExePath(), 1)
If file<>0 Then Print "Ausgewählte Datei: " + *file
End Sub
Sub Speichern Cdecl (widget As Fl_Widget Ptr, userdata As Any Ptr)
Print "Datei speichern"
End Sub
Sub Beenden Cdecl (widget As Fl_Widget Ptr, userdata As Any Ptr)
End
End Sub
Sub Info Cdecl (widget As Fl_Widget Ptr, userdata As Any Ptr)
'Info anzeigen:
flMessageBox("Programm-Information", "Menü-Testprogramm")
End Sub
'Hauptprogramm:
CreateWindow_Main()
Fl_WindowShow(Window_Main)
Fl_Run
End
Hier der Screenshot:
Die Menü-Einträge werden auf sehr einfache Weise mit Fl_Menu_Add erzeugt. Der dritte Parameter kann optional eine Shortcut-Taste für den betreffenden Menüeintrag sein, z.B. FL_CTRL+Asc("b") für "Beenden". Der vierte Parameter verknüpft den Menü-Eintrag mit der zugehörigen Callbackfunktion. Diese muss im Gegensatz zu den bisherigen Beispielen als zweiten Parameter einen Pointer auf userdata enthalten, da mit Fl_Menu_Add eine Verknüpfung mit einer Sub vom Typ Fl_Callback hergestellt wird statt mit einer Sub vom Typ Fl_Callback0 (wie bisher).
Bei den Callbackfunktionen in diesem Beispiel lernen wir auch zwei Standarddialoge kennen: einen flFileChooser und eine flMessageBox.
Der flFileChooser ist ein Dialog zur Dateisuche. Die Syntax ist eigentlich
selbsterklärend, bis auf den letzten Parameter. Dieser hat folgende Bedutung:
1 = relativer Pfad
0 = absoluter Pfad
Die flMessageBox ist eine einfache Messagebox mit nur einem "Close"-Button.
Hier die zugehörigen Screenshots:
flFileChooser:
flMessagebox:
4.8 Weitere Standarddialoge (Common dialogs)
(0hne Screenshots)
Braucht man eine Messagebox, bei der der Benutzer eine Entscheidung treffen kann
(z.B. "Ja", "Nein", "Abbrechen"), also bis zu drei Buttons, so nimmt man einen flChoice.
Beispiel für die Verwendung eines flChoice:
Dim As Integer result
result = flChoice("Wollen Sie das Programm wirklich beenden?", "Ja", "Nein", "Vielleicht")
Select Case result
Case 0
End
Case 1
'.....
Case 2
flMessageBox("Was soll das?", "Sie müssen sich schon entscheiden!")
End Select
Weitere Standarddialoge sind der flColorChooser und flInput.
Der flColorChooser ermöglicht eine Farbwahl mit verschiedenen Einstellungen. Soll die Auswahl und die Ausgabe in RGB-Werten von 0 bis 255 erfolgen, ist dies die Syntax:
Dim As UByte r, g, b
flColorChooser("Wählen Sie eine Farbe", r, g, b, FL_COLORCHOOSER_BYTE)
Print "Gewählte Farbe (r, g, b): ", r, g, b
Die Werte r, g und b können als Vorauswahl im Bereich 0 bis 255 vorgewählt werden.
FL_COLORCHOOSER_BYTE bedeutet, dass diese Werte als Byte-Werte (0 bis 255)
im Colorchooser angezeigt und editiert werden können. Mit anderen Flags sind auch
Anzeigen als Dezimalzahlen im relativen Wertebereich von 0 bis 1 möglich oder
Hexadezimalwerte.
flInput ist ein Fenster mit einer Eingabemöglichkeit, z.B.:
Dim As String s
s = *flInput("Geben Sie Ihren Namen ein:", "Otto Mustermann")
Print s
(in diesem Beispiel kann "Otto Mustermann" editiert werden.)
Zusätzliche Informationen und Funktionen | |||||||
---|---|---|---|---|---|---|---|
|
|