Archive for category GTK+

IHM asynchrone

J’avais parlé d’interface asynchrone dans ce billet.

Cela consiste tout simplement à ce qu’une interface puisse continuer à prendre les évènements de l’utilisateur pendant qu’elle se met à jour.

L’exemple typique est celui d’un treeview mettant un certain temps à se remplir. Dans un programme classique, l’interface sera figée le temps que le treeview soit remplit.

Une interface asynchrone permet d’être mise à jour à mesure, et de répondre aux évènements de l’utilisateur. Pour faire cela le programmeur lambda (moi le premier :) pensera à un thread pour résoudre ce problème.
Le thread contenant la partie du code insérant les données dans le treeview. Il va s’en dire qu’un thread pour cette tâche est plutôt “overkill”. De plus on ajoute un élément rendant le programme difficile à débuguer.

La Glib propose la méthode g_idle_add. Cette fonction permet d’effecter un traitement lorsque la boucle d’évènement de GTK+ idle, c’est à dire lorsqu’il n’y a plus d’évènement hautement prioritaire à gérer.
Cette fonction est bien sûr bindé en RG2 :

GLib::Idle.add { traitement}

Voir l’exemple dans le paquet libglib2-ruby : /usr/share/doc/libglib2-ruby/examples/idle.rb

Ensuite, si vous avez un traitement répétitif à effectuer, il existe la fonction g_timeout_add. Cette fonction exécute votre traitement dans un intervale régulier et selon une priorité définissable. Voir l’exemple dans /usr/share/doc/libglib2-ruby/examples/timeout.rb

Ces deux fonctions permettent d’éviter les threads et rendent votre IHM un peu plus asynchrone. Voir les explications détaillées en C sur ce billet : Lazy Loading Using The Main Loop et un exemple plus simple en python : Re: Lazy loading

Malgré ceci, il se peut que vous deviez forcer GTK+ à se mettre à jour :

while (Gtk.events_pending?)             Gtk.main_iterationend

En gros, tant que GTK+ a des évènement en attente, on lui laisse la main. Ceci me sert à forcer le rafraichissement du treeview des pages jaunes. Pour diverses raisons (callback SAX2) je ne peux pas mettre la boucle alimentant le model du treeview dans un g_idle_add. Cette boucle me permet donc d’arriver à un résultat similaire même si le g_idle_add est à privilégier.

Merci aux conseils de Dodji, teuf et HappyPeng.

Laisser un commentaire

Suivre

Get every new post delivered to your Inbox.

Joignez-vous à 189 followers