Vous êtes à peu près ici : Accueil  »   tutoriel PyGTK  »   PyGTK : sommaire

Chapitre 11. Les menus

Sommaire

11.1. Création manuelle de menus
11.2. Démonstration de création manuelle de menus
11.3. Création de menus avec l'ItemFactory
11.4. Démonstration de l'ItemFactory

Il y a deux méthodes de création des menus : la facile, et la difficile. Toutes deux ont leur utilité, bien que dans la plupart des cas l'ItemFactory (la méthode facile) suffise. La méthode "difficile" consiste à créer tous les menus en les appelant directement, là où la méthode facile utilisera les appels de GtkItemFactory. Même si c'est effectivement beaucoup plus simple, des avantages et des inconvénients existent pour chaque approche.

Il est vrai que l'Itemfactory rend nettement plus simple la création et l'ajout ultérieur de menus ; mais faire la même chose manuellement, à l'aide de quelques fonctions, peut apporter beaucoup en termes d'ergonomie. Avec l'Itemfactory, vous ne pourrez pas ajouter d'images aux menus, ni y faire figurer le caractère "/".

11.1. Création manuelle de menus

Comme le veut la bonne vieille tradition pédagogique, nous commen?s par la méthode difficile :)

Trois widgets entrent en jeu dans la création d'une barre de menus et de ses sous-menus :

  • l'entrée de menu, qui représente ce que l'utilisateur veut faire/choisir (par exemple "Enregistrer")

  • le menu, qui contient les entrées de menu

  • la barre de menus, qui contient les menus.

Mais tout n'est pas si simple. En effet, les entrées de menu servent à deux choses différentes : elles représentent à la fois les widgets placés dans le menu et celui placé dans la barre de menu (celui qui, une fois selectionné, active le menu).

Observons les fonctions servant à créer menus et barres de menus :

  barre_menus = gtk.MenuBar()

Cette première fonction, vous l'aurez deviné, crée une nouvelle barre de menus. On utilisera la méthode add() de GtkContainer pour la placer dans une fenêtre, ou bien les différentes méthodes pack() de GtkBox pour la placer dans une boite (comme pour les boutons).

  menu = gtk.Menu()

Cette fonction renvoie une référence à un nouveau menu ; il n'est jamais concrètement affiché (par la méthode show()), c'est juste un conteneur pour les entrées de menu. Tout ceci vous paraitra, je l'espère, beaucoup plus clair après que vous aurez jeté un œil à l'exemple plus bas.

La fonction ci-dessous sert à créer les entrées qui seront placées dans le menu (et la barre de menus) :

  entree = gtk.MenuItem(label=None)

L'argument label (étiquette), si spécifié, sera parcouru à la recherche de caractères mnémoniques. Cet appel crée les entrées de menu qui doivent apparaitre dans le menu. Attention à ne pas confondre le "menu", créé avec gtk.Menu(), et l'"entrée de menu", créée avec la fonction gtk.MenuItem(). L'entrée sera un véritable bouton, auquel sera associé une action, tandis que le menu sera un conteneur renfermant des entrées.

Une fois votre entrée créée, vous devez la placer dans un menu grâce à la méthode append(). Puis, pour pouvoir réagir à une selection de cette entrée par l'utilisateur, il faudra capter son signal "activate" (activer) de la manière habituelle.

Imaginons que nous voulions créer un menu "Fichier" standard, avec les entrées Ouvrir, Enregistrer, et Quitter. Notre code devrait alors ressembler à ceci :

  menu_fichier = gtk.Menu()    # Inutile d'afficher les menus avec show()

  # Creation des entrees de menu
  entree_ouvrir = gtk.MenuItem("Ouvrir")
  entree_enreg = gtk.MenuItem("Enregistrer")
  entree_quitter = gtk.MenuItem("Quitter")

  # On les place dans le menu
  menu_fichier.append(entree_ouvrir)
  menu_fichier.append(entree_enreg)
  menu_fichier.append(entree_quitter)

  # On connecte les fonctions de rappel au signal "activate"
  entree_ouvrir.connect_object("activate", entrees_reponse, "fichier.ouvrir")
  entree_enreg.connect_object("activate", entrees_reponse, "fichier.enregistrer")

  # On peut connecter la entree Quitter à notre fonction de sortie
  entree_quitter.connect_object ("activate", destroy, "fichier.quitter")

  # Il nous faut afficher les entrees
  entree_ouvrir.show()
  entree_enreg.show()
  entree_quitter.show()

Nous avons maintenant notre menu. Il nous reste à créer une barre de menus, puis une entrée "Fichier" à laquelle nous relierons notre menu. Le code pour ce faire est le suivant :

  barre_menus = gtk.MenuBar()
  fenetre.add(barre_menus)
  barre_menus.show()

  entree_fichier = gtk.MenuItem("Fichier")
  entree_fichier.show()

Maintenant associons le menu avec entree_fichier. On fait appel pour cela à la méthode suivante :

  entree.set_submenu(sous_menu)

Ce qui donnerait, pour la suite de notre exemple :

  entree.set_submenu(menu_fichier)

Tout ce qui nous reste à faire est de placer le menu dans la barre de menus, en utilisant la méthode :

  barre_menus.append(enfant)

... qui, dans notre cas, donne :

  barre_menus.append(entree_fichier)

Si nous voulions aligner notre menu sur la droite de la barre de menus, comme le sont souvent les menus d'aide, nous pourrions faire appel à la méthode ci-dessous (toujours sur entree_fichier dans notre exemple) avant de l'attacher à la barre de menus.

  entree.set_right_justified(align_droite)

Voici un résumé des étapes nécessaires à la céation d'une barre de menus avec ses menus :

  • Créez un nouveau menu avec gtk.Menu()

  • Faire un appel à gtk.MenuItem() pour chaque entrée que vous voulez voir figurer dans votre menu. Puis utilisez la méthode append() pour placer chacune de ces nouvelles entrées dans le menu.

  • Créez une entrée avec gtk.MenuItem(). Ce sera la racine du menu, son étiquette apparaitra directement dans la barre de menus.

  • Utilisez la méthode set_submenu() pour attacher le menu à l'entrée racine (celle créée à l'étape précédente).

  • Créez une barre de menu avec gtk.MenuBar(). Si l'on crée une série de menus que l'on veut placer sur une seule barre de menus, cette étape n'a besoin d'être effectuée qu'une seule fois.

  • Utilisez la méthode append() pour placer la racine dans la barre de menus.

Le procédé de création d'un menu popup est plus ou moins identique. La différence est que le menu n'est pas affiché "automatiquement" par une barre de menus, mais explicitement par un appel à la méthode popup(), lors d'un évènement "button-press"par exemple. Procédez comme suit :

  • Créez une fonction de rappel gestionnaire d'évènement. Elle doit être de la forme :

      def fct_rappel(widget, evenement):
    
  • ... et utilisera l'évènement pour savoir où afficher le menu.

  • Dans le gestionnaire d'évènement, si l'évènement est une pression d'un bouton de la souris, traitez le comme un évènement bouton (ce qu'il est) et utilisez-le comme montré dans l'exemple de code pour transmettre l'information à la méthode popup().

  • Attachez ce gestionnaire d'évènement à un widget ainsi :

      widget.connect_object("evenement", fct_rappel, menu)
    
  • ... où widget est le widget auquel vous connectez l'évènement, fct_rappel la fonction de rappel, et menu le menu crée par GtkMenu(). Ce dernier peut aussi être affiché par une barre d'état, comme dans notre code.