GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt GUI-Programmierung Packing in Haskell Widgets HBox, VBox Button Entry Label Uwe Schäfer Glade Ausblick und Fazit Fachbereich Mathematik und Informatik der Philipps-Universität Marburg 8. Februar 2010 Wichtige Begriffe GUI? Kann man das essen? GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt I GUI = Graphical User Interface (1970) Packing I GUI wird zusamengepuzzelt aus vielen Einzelteilen: Widgets = Window gadgets (1988) Widgets HBox, VBox Button Entry I GTK+ = GIMP Toolkit (1998) GIMP = General/GNU Image Manipulation Program (1996) Label Glade Ausblick und Fazit Inhalt GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt Einführung GUIs mit Haskell Hallo Welt Packing HBox, VBox Widgets Packing HBox, VBox Button Entry Label Glade Widgets Button Entry Label Glade Ausblick und Fazit Ausblick und Fazit GUI-Anbindungen für Haskell Argumente für Gtk2Hs GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt Packing HBox, VBox I Viele GUI-Anbindungen für Haskell verfügbar I Zu den bekanntesten zählen wxHaskell und Gtk2Hs Widgets Button Entry I Vorteil von Gtk2Hs: benutzerfreundlich, plattformübergreifend mit GTK, einfache Erstellung von GUIs über XML-Beschreibungen, automatisches Speichermanagement Label Glade Ausblick und Fazit Ein erstes Programm mit Gtk2Hs Hallo Welt! GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt import Graphics . UI . Gtk main :: IO () main = do initGUI window ← windowNew button ← buttonNew set window [ containerChild := button ] set button [ buttonLabel := " Hello world ! " ] onClicked button ( putStrLn " Hello world ! " ) onDestroy window mainQuit widgetShowAll window mainGUI I Gtk2Hs-Bibliothek einbinden Packing HBox, VBox Widgets Button Entry Label Glade Ausblick und Fazit Ein erstes Programm mit Gtk2Hs Hallo Welt! GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt import Graphics . UI . Gtk main :: IO () main = do initGUI window ← windowNew button ← buttonNew set window [ containerChild := button ] set button [ buttonLabel := " Hello world ! " ] onClicked button ( putStrLn " Hello world ! " ) onDestroy window mainQuit widgetShowAll window mainGUI I Benutzereingaben → IO()-Monade Packing HBox, VBox Widgets Button Entry Label Glade Ausblick und Fazit Ein erstes Programm mit Gtk2Hs Hallo Welt! GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt import Graphics . UI . Gtk main :: IO () main = do initGUI window ← windowNew button ← buttonNew set window [ containerChild := button ] set button [ buttonLabel := " Hello world ! " ] onClicked button ( putStrLn " Hello world ! " ) onDestroy window mainQuit widgetShowAll window mainGUI I Imperativer Ablauf des Aufbaus, Gtk2Hs initialisieren Packing HBox, VBox Widgets Button Entry Label Glade Ausblick und Fazit Ein erstes Programm mit Gtk2Hs Hallo Welt! GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt import Graphics . UI . Gtk main :: IO () main = do initGUI window ← windowNew button ← buttonNew set window [ containerChild := button ] set button [ buttonLabel := " Hello world ! " ] onClicked button ( putStrLn " Hello world ! " ) onDestroy window mainQuit widgetShowAll window mainGUI I Fenster und Button erstellen Packing HBox, VBox Widgets Button Entry Label Glade Ausblick und Fazit Ein erstes Programm mit Gtk2Hs Hallo Welt! GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt import Graphics . UI . Gtk main :: IO () main = do initGUI window ← windowNew button ← buttonNew set window [ containerChild := button ] set button [ buttonLabel := " Hello world !" ] onClicked button ( putStrLn " Hello world ! " ) onDestroy window mainQuit widgetShowAll window mainGUI I Button ins Fenster packen und beschriften Packing HBox, VBox Widgets Button Entry Label Glade Ausblick und Fazit Ein erstes Programm mit Gtk2Hs Hallo Welt! GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt import Graphics . UI . Gtk main :: IO () main = do initGUI window ← windowNew button ← buttonNew set window [ containerChild := button ] set button [ buttonLabel := " Hello world ! " ] onClicked button ( putStrLn " Hello world !") onDestroy window mainQuit widgetShowAll window mainGUI I Reaktionen auf Eingaben festlegen Packing HBox, VBox Widgets Button Entry Label Glade Ausblick und Fazit Ein erstes Programm mit Gtk2Hs Hallo Welt! GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt import Graphics . UI . Gtk main :: IO () main = do initGUI window ← windowNew button ← buttonNew set window [ containerChild := button ] set button [ buttonLabel := " Hello world ! " ] onClicked button ( putStrLn " Hello world ! " ) onDestroy window mainQuit widgetShowAll window mainGUI I Eingabeschleife starten Packing HBox, VBox Widgets Button Entry Label Glade Ausblick und Fazit Demo Hallo Welt GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt Packing HBox, VBox Widgets Button Entry Label Glade Ausblick und Fazit Packing Was benötigt man, wenn man mehr als einen Button nutzen möchte? GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt Packing HBox, VBox I Problem: Ein Fenster, das von sich aus mehr als ein Widget enthalten kann, gibt es nicht Widgets Button Entry Label I I Daher: Verwendung von Containern (= Widgets, die Widgets aufnehmen können) Es gibt verschiedene Formen von Containern: HBox, VBox, Table, Notebook, Expander, HPaned, VPaned, Fixed, ... Glade Ausblick und Fazit Packing: HBox, VBox Widgets horizontal oder vertikal anordnen GUIProgrammierung Uwe Schäfer Einführung I Einfachste Anordnung: mit HBox und VBox hBoxNew :: Bool → Int → IO HBox vBoxNew :: Bool → Int → IO VBox GUIs mit Haskell Hallo Welt Packing HBox, VBox Widgets Button I HBox und VBox lassen sich auf verschiedene Weisen packen boxPackStart , boxPackEnd :: ( BoxClass self , WidgetClass child ) ⇒ self -- Container → child -- Widget → Packing -- Packart → Int -- zus . Abstand → IO () I Typ Packing: PackGrow, PackRepel, PackNatural Entry Label Glade Ausblick und Fazit Demo Packing in hBox und boxPackStart/boxPackEnd GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt Packing HBox, VBox Widgets Button Entry Label Glade Ausblick und Fazit GUIProgrammierung Widgets Was steht uns – außer Buttons – noch zur Verfügung? Uwe Schäfer Einführung I I Button: gewöhnliche Schaltfläche ToggleButtons: I I I I ToggleButton: Schaltfläche mit Statuswechsel CheckButton: Feld zum Setzen eines Häkchens RadioButton: Feld zur Auswahl einer Option aus mehreren Adjustments I I I SpinButton: Werteauswahl bis 20 Stellen Genauigkeit Scrollbar Scale: Werteauswahl bis 64 Stellen Genauigkeit GUIs mit Haskell Hallo Welt Packing HBox, VBox Widgets Button Entry Label Glade Ausblick und Fazit Widgets senden Signale Verarbeiten von Ereignissen auf der Benutzeroberfläche GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt Packing HBox, VBox Widgets I Was passiert, wenn auf eine Schaltfläche geklickt wird oder Jemand eine Eingabe in einem Textfeld bestätigt? Button Entry Label Glade I Signals werden gesendet (unterschiedlich je nach Widget) I werden je nach Widget auch unterschiedlich verarbeitet Ausblick und Fazit Widgets haben Attribute Eigenschaften von Widgets können vielseitig sein GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt Packing I jedes Widget hat ein Set von bestimmten Eigenschaften (z. B. die Beschriftung eines Buttons oder die Größe eines Fensters) Widgets lesen mit get und schreiben mit set: Glade HBox, VBox Button Entry Label I get :: o → ReadWriteAttr o a b → IO a set :: o → [ AttrOp o ] → IO () value ← get widget attribute set widget [ attribute := value ] Ausblick und Fazit Widgets: Button GUIProgrammierung Schaltflächen mit Gtk2Hs Uwe Schäfer I Einführung Konstruktoren: GUIs mit Haskell Hallo Welt buttonNew button Ne wW it hL ab el but to n N e w W i t h M n e moni c button Ne wF ro mS to ck :: :: :: :: IO Button String → IO Button String → IO Button StockId → IO Button Packing HBox, VBox Widgets Button Entry Label I Signals: onClicked, onPressed, onEnter, onLeave, onButtonActivate :: ButtonClass b ⇒ b → IO () → IO ( ConnectId b ) I Beispielaktion nach erfolgtem Klick: onClicked button ( putStrLn " Hello world ! " ) ConnectId kann auch gespeichert werden, falls spätere Veränderung der Aktion gewünscht Glade Ausblick und Fazit GUIProgrammierung Widgets: Entry Eingabefelder mit Gtk2Hs Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt I Konstruktor: Packing entryNew :: IO Entry Widgets HBox, VBox Button Entry I interessante Attribute: entryEditable, entryVisibility, entryInvisibleChar, entryMaxLength, entryWidthChars entrySetText ⇒ self → entryGetText ⇒ self → I :: EntryClass self String → IO () :: EntryClass self IO String wichtigstes Signal: onEntryActivate Label Glade Ausblick und Fazit GUIProgrammierung Widgets: Label Beschriftungen mit Gtk2Hs Uwe Schäfer Einführung I Konstruktoren: GUIs mit Haskell Hallo Welt labelNew :: Maybe String → IO Label label N e w W i t h M n e m onic :: String → IO Label Packing HBox, VBox Widgets Button I wichtigstes Attribut (Beschriftung): Entry Label labelGetText , :: LabelClass labelSetText , :: LabelClass I labelGetLabel self ⇒ self → IO String labelSetLabel self ⇒ self → String → IO () Labels unterstützen Pango-Markup labelSetMarkup :: LabelClass self ⇒ self → Markup → IO () l a b e l S e t M a r k u p W i t h M n e m o n i c :: LabelClass self ⇒ self → Markup → IO () Glade Ausblick und Fazit Demo Erweitertes Hallo-Welt-Programm GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt Packing HBox, VBox Widgets Button Entry Label Glade Ausblick und Fazit Entwicklung von Oberflächen mit Glade Man muss nicht alles von Hand erledigen GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt Packing HBox, VBox Widgets Button I Programmieren von Oberflächen kann viel Zeit in Anspruch nehmen I Erleichterung dieser Arbeit durch Glade I GUIs in WYSIWYG-Form entwickeln Entry Label Glade Ausblick und Fazit Demo Glade verwenden GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt Packing HBox, VBox Widgets Button Entry Label Glade Ausblick und Fazit GladeXML verwenden Benutzung einer in Glade erstellten Oberfläche mit Gtk2Hs I Weiteres Paket nötig: GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt import Graphics . UI . Gtk . Glade Packing Einlesen der Beschreibung mit Widgets HBox, VBox I xmlNew :: FilePath → IO ( Maybe GladeXML ) Button Entry Label Glade I Parsen der einzelnen Widgets mit xmlGetWidget :: ( WidgetClass widget ) ⇒ GladeXML → ( GObject → widget ) -- Cast - Funktion → String -- Bezeichner → IO widget window ← xmlGetWidget windowXml castToWindow " mainWindow " Ausblick und Fazit Demo GladeXML in Gtk2Hs GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt Packing HBox, VBox Widgets Button Entry Label Glade Ausblick und Fazit Erfahrungen und Ausblick Programmieren mit Gtk2Hs macht Spaß I positiv: I I I I I gewöhnungsbedüftig: I I I Entwicklung alltagstauglicher Programme ist mit Gtk2Hs gut möglich gute Unterstützung der aktuellen GTK+-API gut dokumentiert, kann deutlich mehr als hier gezeigt werden konnte einfache Entwicklung komplexerer GUIs mit Glade möglich Verarbeitung von Signals nicht überall einheitlich viele Tutorials schon wieder veraltet – zugleich aber auch ein positives Zeichen: Entwicklung geht gut voran weitere Themen: I I Aufbau eines komplett funktionalen GUIs Cairo-Unterstützung, OpenGL, GStreamer (Streaming Media), GConf, ... GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt Packing HBox, VBox Widgets Button Entry Label Glade Ausblick und Fazit Fazit Es lohnt sich! GUIProgrammierung Uwe Schäfer Einführung GUIs mit Haskell Hallo Welt Packing I Beschäftigung mit Gtk2Hs ist eine lohnende Angelegenheit HBox, VBox Widgets Button Entry I I bereits jetzt sehr umfangreich und zeigt einen für die Zukunft sehr vielversprechenden Drang nach Weiterentwicklung Vielen Dank! Label Glade Ausblick und Fazit