Création de widget GTK+ en python sous Maemo5

En dépiThe new GTK+ logo.t de mon idée première de dériver de la classe gtk.Widget, ne maîtrisant pas toutes les subtilités de GTK+, je me suis rabattu sur la solution de spécialiser la classe gtk.DrawingArea.

La classe GenTree du projet Maegen illustre comment il est aisé de fabriquer ses propres widgets ! Dans cette exemple le widget n’est pas interactif et il se contente de se dessiner. C’est déjà un début.

L’interaction avec l’utilisateur se fera simplement en s’abonant aux événements et ne devrait pas poser de difficultés. Ma seule inquiètude se situe dans la capacité à s’interfacer avec les autres conteneurs GTK tels que les Aligment etc. Un widget bien élevé doit être capable d’adapter sa taille en fonction de son conteneur. Peut-on le faire avec un DrawingArea ?

Créer un widget GTK en python sous Maemo5

GTK Widgets
Image by crafterm via Flickr

Dans le développement de Maegen j’ai eu envie de créer une vue affichant l’arbe généalogique de manière arborescente. Pour cela j’ai utilisé un gtk.DrawingArea dans lequel je dessine l’arbre. Les méthodes de dessin et les diverses variables sont portées par la fenêtre qui contient le gtk.DrawingArea.

L’envie de réutiliser cette arbre ailleur qu’en pleine fenêtre m’invite à en faire un widget à part entière que je pourrai mettre dans une fenêtre ou tout autre widget conteneur.

Le site learningpython montre un exemple de création de widget personnalisé et l’exemple fonctionne quasiment parfaitement sur Ubuntu 11.04. Quasiment car le widget ne s’affiche que si on redimensionne la fenêtre. Je me lance alors dans un refatoring pour extraire le code de dessin et le mettre dans une classe dérivant de gtk.Widget. Voir le code ici.

Le premier problème vient d’une inattention fébrile à l’idée de créer mon premier widget… L’oublie de la ligne suivante:

# register the class as a Gtk widget
gobject.type_register(MyOwnWidgetClass)

qui est obligatoire sinon la méthode __init__() de la classe gtk.Widget refuse de s’éxécuter sur la classe dérivée.

Malheueusement une fois cette ligne ajoutée, le widget reste définivement vide sans le moindre petit arbre dedans. En y regardant de plus près, la méthode do_expose_event() n’est pas appelée. Cela est encore pour moi un mystère…

Quoiqu’il en soit il y a un contournement qui consiste à dériver de gtk.DrawingArea pour créer mon widget. Cette solution est sans doute la plus simple compte tenu du fait que mon code de départ manipule un DrawingArea ! Le site suivant montre une telle réalisation : zetcode.com