aboutsummaryrefslogtreecommitdiff
path: root/content/Informatique/2014-02-09-ocaml_gtk.rst
diff options
context:
space:
mode:
Diffstat (limited to 'content/Informatique/2014-02-09-ocaml_gtk.rst')
-rw-r--r--content/Informatique/2014-02-09-ocaml_gtk.rst206
1 files changed, 0 insertions, 206 deletions
diff --git a/content/Informatique/2014-02-09-ocaml_gtk.rst b/content/Informatique/2014-02-09-ocaml_gtk.rst
deleted file mode 100644
index 09f1aee..0000000
--- a/content/Informatique/2014-02-09-ocaml_gtk.rst
+++ /dev/null
@@ -1,206 +0,0 @@
-.. -*- rst -*-
-.. -*- coding: utf-8 -*-
-
-=======================================
-Trois manière d'utiliser Gtk avec OCaml
-=======================================
-
-:date: 2014-02-09
-:tags: ocaml, gtk
-:summary: |summary|
-:logo: /images/ocaml/camel_75.jpg
-
-.. default-role:: literal
-
-.. figure:: {filename}/images/ocaml/camel_2.jpg
- :figwidth: 150
- :figclass: floatleft
- :alt: Pavement
-
- Image : `Kevin Botto`_ (creativecommons_)
-
-.. _Kevin Botto: http://www.flickr.com/photos/kevinbotto/3251157974/
-.. _creativecommons: http://creativecommons.org/licenses/by-nd/2.0/deed.fr
-
-|summary|
-
-
-.. |summary| replace::
- Créer des interfaces Gtk pour OCaml peut se réveler compliquer. On trouve
- beaucoup d'explications un peu confuses sur le net, et n'est pas facile de
- trouver comment faire.
- Je vous propose ici trois manières différentes en utilisants les différents
- outils disponibles.
-
-Il est possible d'utiliser la bibliothèque Gtk à l'aide de la librairie
-lablgtk_, qui fourni un binding pour l'ensemble de la bibliothèque. L'avantage
-est de pouvoir fonctionner sur toutes les plateformes où gtk est disponible, et
-de bénéficier d'une interface évoluée et agréable pour écrire son application.
-
-L'inconvénient réside dans la bibliothèque gtk : api très compliquée,
-documentation confuse, bref on se retrouve rapidement face à des problèmes là
-où l'on pensait pouvoir avancer sans difficulté. De plus, on est aujourd'hui
-passé à gtk3 alors que `lablgtk` utilise toujours l'api de gtk2. Cela ne pose pas
-de problème dans la compilation (la compatibilité est assurée), mais peut poser
-problème lors de l'utilisation d'outils tels que `glade` (voir plus loin).
-
-.. _lablgtk: http://lablgtk.forge.ocamlcore.org/
-
-Tout construire à la main
-=========================
-
-C'est la première solution, qui demande de connaître Gtk : tous les objets sont
-construits à la main, et le code décrit la manière de faire. L'avantage est que
-le code ne dépend d'aucune ressource externes contrairement aux deux suivantes.
-De plus on contrôle complètement la création de l'interface, on peut donc
-choisir de paramétrer l'interface au lieu d'avoir une interface unique. Un
-tutoriel complet est disponible sur le site d'`OCaml.org`_, je ne vais pas
-le reprendre ici et vous encourage à le suivre.
-
-.. _ocaml.org: http://ocaml.org/learn/tutorials/introduction_to_gtk.html
-
-L'exemple est donné dans la console interactive. Si l'on souhaite le compiler
-dans un module, il faut initialiser Gtk avant de lancer l'affichage :
-
-.. code-block:: ocaml
-
- GtkMain.Main.init ();
-
-Pour compiler un module, il est nécessaire de faire référence au package
-`lablgtk2`. Voici un exemple pour compiler un fichier `hello.ml` :
-
-.. code-block:: console
-
- $ ocamlfind ocamlc -package lablgtk2 -I . -c hello.ml
-
-Maintenant il ne reste plus qu'à se plonger dans la documentation de gtk pour
-construire son interface !
-
-Utiliser Glade
-==============
-
-Glade est une interface graphique permettant de construire son application en
-plaçant les contrôles de manière visuelle. Elle génère un fichier XML qui
-décrit l'interface et sera chargé par l'application pour construire
-l'interface. Cela permet de gagner du temps et d'éviter d'écrire le code
-nécessaire pour construire son interface, on se concentre sur les actions
-à exécuter lorsque l'utilisateur interagit.
-
-.. image:: {filename}/images/glade.jpg
- :class: center
- :alt: Utilisation de glade.
-
-
-Les XMLs générés par glade sont destinés à être utilisés avec gtk3. Or,
-`lablgtk` utilise encore gtk2, il est donc nécessaire d'utiliser une conversion
-pour pouvoir les charger par la suite. Voici une petite règle `make` qui se
-charge de faire le travail :
-
-.. code-block:: make
-
- %.glade2: %.glade
- cat $< | sed 's/interface/glade-interface/' | sed 's/object/widget/' | sed 's/GtkBox/GtkVBox/' > $@
-
-Maintenant qu'on dispose d'un fichier au format glade2, on peut le charger dans
-OCaml.
-
-Attention, lors de la compilation, il est nécessaire d'utiliser `libglade` pour
-construire l'application, celle-ci est disponible dans la librairie
-`lablgtk2.glade`. Voici donc un exemple de commande pour compiler un fichier
-`hello.ml` :
-
-.. code-block:: console
-
- $ ocamlfind ocamlc -package lablgtk2.glade -I . -c hello.ml
-
-.. _gtkbuilder: https://developer.gnome.org/gtk3/3.4/GtkBuilder.html
-
-Charger le fichier xml
-----------------------
-
-Il s'agit de la solution la plus dynamique : on référence le fichier xml dans
-le code, et l'interface se construit toute seule. Cette solution est présentée
-sur le site de `developpez.com`_. L'exemple donné est toujours valide, il ne
-faut pas oublier d'initialiser Gtk avec la commande suivante avant de lancer la
-construction de l'interface :
-
-.. code-block:: ocaml
-
- GtkMain.Main.init ();
-
-L'inconvénient de cette méthode (du moins pour un développeur OCaml) est que
-l'on est obligé de convertir de manière dynamique tous les objets présents dans
-le XML. Il n'est pas possible de savoir au moment de la compilation si le code
-que l'on va exécuter est bien valide.
-
-En effet, les objets chargés depuis le XML nous sont retournés sous la forme
-widget gtk, qu'il faut convertir en Bouton, Menu via les méthodes appropriées
-(`GtkWindow.Window.cast` par exemple). On n'est donc pas à l'abri d'avoir une
-erreur lors du fonctionnement du programme, alors que celui-ci a pu compiler
-sans problème. Je pense que lorsqu'on cherche à développer en OCaml, ce genre
-de problème peut être rédhibitoire.
-
-.. _developpez.com: http://blog.developpez.com/damien-guichard/p7748/programmation-fonctionnelle/hello_developpez_avec_libglade_xml_1
-
-De plus, rien ne garantie que le fichier XML ne va pas évoluer de manière
-incompatible du code ; les deux étant distincts.
-
-
-Utiliser lablgladecc2
----------------------
-
-Heureusement, la librairie `lablgtk2` nous fourni un petit utilitaire nommé
-`lablgladecc2` qui va convertir un fichier xml glade2 en un fichier OCaml. On
-dispose donc d'un chargement dynamique du fichier xml, mais en gardant un code
-cohérent, qui détectera les erreurs dès la compilation. Il s'agit en quelque
-sorte d'un moyen de combiner les deux solutions précédentes.
-
-On va ajouter une règle au makefile pour générer notre fichier OCaml :
-
-.. code-block:: make
-
- %.ml: %.glade2
- lablgladecc2 -embed $< > $@
-
-Le fichier généré se compose d'une classe reprenant les différents composants
-de notre interface, il ne nous reste plus qu'à réaliser les connexions, ainsi,
-à partir d'un fichier glade nommé *gui* composé d'une fenêtre `window1`, d'un
-bouton `button` et d'une entrée de menu, on peut créer le code suivant :
-
-.. code-block:: ocaml
-
- let gladecc () =
- let window = new Gui.window1 () in
-
- window#button#connect#clicked (fun () -> prerr_endline "Ouch!");
- window#window1#connect#destroy GMain.quit;
- window#imagemenuitem5#connect#activate GMain.quit;
-
- window#toplevel#show ()
-
- let () =
- GtkMain.Main.init ();
- gladecc ();
- GMain.Main.main ()
-
-
-l'objet `toplevel` est créé par `lablgladecc2` et correspond à la fenêtre
-principale de notre objet.
-
-Dans cette chaîne de compilation, le fichier xml est écrit dans le programme
-OCaml (il s'agit de la signification de l'option `-embed`), ainsi, le fichier
-XML n'a pas besoin de figurer parmi les ressources de l'application.
-
-Conclusion
-==========
-
-Trois manière de faire qui répondent à trois besoin différents, entre le tout
-codé et le tout dynamique, il est possible de créer des interfaces graphiques
-en utilisant les capacités du langage caml sur l'inférence de type et le
-contrôle de l'ensemble de l'application.
-
-Pour ma part, je préfère la dernière solution, qui permet de conserver la
-simplicité de `glade` combiné avec la force du langage OCaml. J'ai écrit cet
-article suite à pas mal d'errance sur le net pour trouver les informations
-nécessaires, j'espère que la documentation va évoluer par la suite et permettre
-de faire ce genre de choses plus facilement…