Ceci est une ancienne révision du document !
Comme je n'ai pas envie de réinventer la poudre à chaque fois, je mettrai ici des modèles qui marchent pour réaliser une barre de menu, et je les enrichirai au fur et à mesure.
La barre de menu, située en haut de la fenêtre, comporte ici 2 items: “Fichier” et “Aide”. Un clic sur l'un de ces 2 items fait apparaitre une petite fenêtre avec des items qui, lorsqu'ils sont cliqués par la souris, déclenchent des actions décrites dans les fonctions appelées (Ouvrir, Fermer, etc…).
Vous noterez aussi l'option “underline=” qui désigne le caractère de l'item qui sera souligné et qui permettra à l'item d'être appelé directement au clavier par alt-caractère. Les enchainements de plusieurs commandes alt sont possibles, à condition de ne pas relâcher la touche alt entre 2 commandes.
#!/usr/bin/python # -*- coding: utf-8 -*- import Tkinter class Application(Tkinter.Frame): def __init__(self, master=None): Tkinter.Frame.__init__(self, master, background="grey") # creation de la barre de menu: self.barremenu = Tkinter.Menu(self.master) # creation du menu "Fichier" self.fichier = Tkinter.Menu(self.barremenu, tearoff=0) self.barremenu.add_cascade(label="Fichier", underline=0, menu=self.fichier) self.fichier.add_command(label="Ouvrir", underline=0, command=self.ouvrir) self.fichier.add_command(label="Fermer", underline=0, command=self.fermer) self.fichier.add_command(label="Enregistrer", underline=0, command=self.enregistrer) self.fichier.add_command(label="Quitter", underline=0, command=self.quitter) # creation du menu "Aide" self.aide = Tkinter.Menu(self.barremenu, tearoff=0) self.barremenu.add_cascade(label="Aide", underline=0, menu=self.aide) self.aide.add_command(label="Manuel", underline=0, command = self.manuel) self.aide.add_command(label="A propos", underline=0, command = self.apropos) # afficher le menu self.master.config(menu=self.barremenu) def ouvrir(self): print "Ouvrir" def fermer(self): print "fermer" def enregistrer(self): print "enregistrer" def quitter(self): self.master.destroy() def manuel(self): print "manuel" def apropos(self): print "apropos" ############################################################################# fen=Tkinter.Tk() fen.title("Ma fenêtre") app=Application(fen) fen.geometry("%dx%d%+d%+d" % (300,300,100,100)) fen.mainloop()
Pour construire un item de menu désactivé au démarrage de la fenêtre, il suffit d'ajouter l'option “state=Tkinter.DISABLED” dans la liste des options d'un add_commande.
Par exemple, pour avoir l'item “Enregistrer” du menu Fichier désactivé au départ:
self.fichier.add_command(label="Enregistrer", underline=0, state=Tkinter.DISABLED, command=self.enregistrer)
Pour réactiver l'item à partir d'une des méthodes appelées (l'item est le 3ème item du menu, donc à l'indice 2):
self.fichier.entryconfig(2,state=Tkinter.NORMAL)
et pour désactiver de nouveau:
self.fichier.entryconfig(2,state=Tkinter.DISABLED)
Pour faire la même chose avec l'un des items de la barre de menu, par exemple ici, l'item “Aide”:
Pour désactiver l'item au départ:
self.barremenu.add_cascade(label="Aide",menu=self.aide, state=Tkinter.DISABLED)
Pour l'activer à partir d'une méthode:
self.barremenu.entryconfigure(3,state=Tkinter.NORMAL)
Et pour le désactiver de nouveau:
self.barremenu.entryconfigure(3,state=Tkinter.DISABLED)
Vous noterez une différence avec le cas précédent: l'item “Aide” de la barre de menu est le 3ème menu, son index devrait être “2” et en fait il est “3” (???).
Il suffit d'ajouter entre deux items du menu, la méthode .add_separator(). Par exemple, dans le code précédent, ajoutez avant l'item “Quitter” du menu Fichier:
self.fichier.add_separator()
Par exemple, entre l'item “Fichier” et l'item “Aide” de la barre de menu, on va ajouter un item “Calculer” qui, lorsqu'il sera cliqué, déclenchera directement une action:
Dans le code de base ci-dessus, avant la création de l'item “Aide”, ajoutez simplement:
self.barremenu.add_command(label="Calculer", command=self.calculer)
Et, bien sûr, la méthode qui va être appelée:
def calculer(self): print "calculer"
Par exemple, on va ajouter dans le menu “Fichier” un item qui s'appelle “Drapeau”, qui pourra avoir une coche devant.
A chaque fois qu'on le sélectionne, il change (coché → non-coché → coché → etc…)
self.drap=Tkinter.IntVar() self.drap.set(0) # initialisation: item non coché au départ self.fichier.add_checkbutton(label="Drapeau", command=self.drapeau, variable=self.drap)
Si la coche doit être mise au départ, il suffit d'initialiser la variable self.drap avec 1:
self.drap.set(1)
Et bien sûr, la méthode appelée qui fait des choses différentes en fonction de la valeur de self.drap.get():
def drapeau(self): #on peut tester ici self.drap.get() qui passe a 0 ou a 1 selon la coche de l'item "drapeau" du menu. print "drapeau"
On va placer 3 items dans le menu Action, qui comporteront une coche devant pour le dernier item sélectionné.
Les choix s'excluent: la sélection d'un item le coche, mais aussi décoche l'item précédemment choisi (comme des boutons radio).
Vous voyez l'utilisation de la variable nitem de type Tkinter.IntVar(). Elle est mise à 1 au départ (=1er choix coché). Elle est ensuite mise à 1, 2 ou 3 selon le dernier choix effectué. Les 3 items du choix exclusif appellent la même méthode (ici item()) qui peut tester le dernier choix fait (=la valeur de nitem) par self.nitem.get().
#!/usr/bin/python # -*- coding: utf-8 -*- import Tkinter class Application(Tkinter.Frame): def __init__(self, master=None): Tkinter.Frame.__init__(self, master, background="grey") # creation de la barre de menu: self.barremenu = Tkinter.Menu(self.master) # creation du menu "Fichier" self.fichier = Tkinter.Menu(self.barremenu, tearoff=0) self.barremenu.add_cascade(label="Fichier",menu=self.fichier) self.fichier.add_command(label="Ouvrir", command=self.ouvrir) self.fichier.add_command(label="Fermer", command=self.fermer) self.fichier.add_command(label="Enregistrer", command=self.enregistrer) self.fichier.add_command(label="Quitter", command=self.quitter) # creation du menu "Action" self.action = Tkinter.Menu(self.barremenu, tearoff=0) self.barremenu.add_cascade(label="Action",menu=self.action) self.action.add_command(label="Format", command=self.format) self.action.add_separator() self.nitem=Tkinter.IntVar() self.nitem.set(1) self.action.add_radiobutton(label="item1", command=self.item, variable=self.nitem, value=1) self.action.add_radiobutton(label="item2", command=self.item, variable=self.nitem, value=2) self.action.add_radiobutton(label="item3", command=self.item, variable=self.nitem, value=3) self.action.add_separator() self.action.add_command(label="Configuration", command=self.configuration) # creation du menu "Aide" self.aide = Tkinter.Menu(self.barremenu, tearoff=0) self.barremenu.add_cascade(label="Aide",menu=self.aide) self.aide.add_command(label="Manuel", command = self.manuel) self.aide.add_command(label="A propos", command = self.apropos) # afficher le menu self.master.config(menu=self.barremenu) def ouvrir(self): print "Ouvrir" def fermer(self): print "fermer" def enregistrer(self): print "enregistrer" def quitter(self): self.master.destroy() def format(self): print "format" def item(self): print "item: ", self.nitem.get() def configuration(self): print "configuration" def manuel(self): print "manuel" def apropos(self): print "apropos" ############################################################################# fen=Tkinter.Tk() fen.title("Ma fenêtre") app=Application(fen) fen.geometry("%dx%d%+d%+d" % (300,300,100,100)) fen.mainloop()
On va faire en sorte que l'item “Titre” du menu “Action” affiche un fenêtre supplémentaire avec des items de menu à sélectionner.
On voit aussi dans cet exemple comment on peut transmettre une valeur en sélectionnant un item de menu avec lambda:
#!/usr/bin/python # -*- coding: utf-8 -*- import Tkinter class Application(Tkinter.Frame): def __init__(self, master=None): Tkinter.Frame.__init__(self, master, background="grey") # creation de la barre de menu: self.barremenu = Tkinter.Menu(self.master) # creation du menu "Fichier" self.fichier = Tkinter.Menu(self.barremenu, tearoff=0) self.barremenu.add_cascade(label="Fichier",menu=self.fichier) self.fichier.add_command(label="Ouvrir", command=self.ouvrir) self.fichier.add_command(label="Fermer", command=self.fermer) self.fichier.add_command(label="Enregistrer", command=self.enregistrer) self.fichier.add_command(label="Quitter", command=self.quitter) # creation du menu "Action" self.action = Tkinter.Menu(self.barremenu, tearoff=0) self.barremenu.add_cascade(label="Action",menu=self.action) self.action.add_command(label="Format", command=self.format) # creation du sous-menu "Titre" du menu "Action" self.titre = Tkinter.Menu(self.action, tearoff=0) self.action.add_cascade(label="Titre",menu=self.titre) self.titre.add_command(label="Demo", command=lambda : self.changetitre('Demo')) self.titre.add_command(label="Test", command=lambda : self.changetitre('Test')) self.action.add_command(label="Configuration", command=self.configuration) # creation du menu "Aide" self.aide = Tkinter.Menu(self.barremenu, tearoff=0) self.barremenu.add_cascade(label="Aide",menu=self.aide) self.aide.add_command(label="Manuel", command = self.manuel) self.aide.add_command(label="A propos", command = self.apropos) # afficher le menu self.master.config(menu=self.barremenu) def ouvrir(self): print "Ouvrir" def fermer(self): print "fermer" def enregistrer(self): print "enregistrer" def quitter(self): self.master.destroy() def format(self): print "format" def changetitre(self,choix): self.master.title(choix) def configuration(self): print "configuration" def manuel(self): print "manuel" def apropos(self): print "apropos" ############################################################################# fen=Tkinter.Tk() fen.title("Ma fenêtre") app=Application(fen) fen.geometry("%dx%d%+d%+d" % (300,300,100,100)) fen.mainloop()
On va utiliser la même solution qu'avec les autres widgets.
1- Importer tkFont en plus de Tkinter (attention: les majuscules comptent!)
2- Instancier la classe tkFont.Font(), par exemple policemenu=tkFont.Font(), et lui fournir comme arguments les caractéristiques de la police voulue.
3- ajouter l'option “font=policemenu” à la création de chacun des items de la barre de menu.
NB: on ne change pas la police de la barre des menus elle-même, mais seulement des fenêtres d'items qui sont appelées par eux.
Les options possibles sont:
Exemple: dans le code suivant, les items du menu apparaissent en arial gras italic taille 10:
#!/usr/bin/python # -*- coding: utf-8 -*- import Tkinter, tkFont class Application(Tkinter.Frame): def __init__(self, master=None): Tkinter.Frame.__init__(self, master, background="grey") policemenu=tkFont.Font(self, size=10, family='Arial', weight=tkFont.BOLD, slant=tkFont.ITALIC) # creation de la barre de menu: self.barremenu = Tkinter.Menu(self.master) # creation du menu "Fichier" self.fichier = Tkinter.Menu(self.barremenu, tearoff=0, font=policemenu) self.barremenu.add_cascade(label="Fichier",menu=self.fichier) self.fichier.add_command(label="Ouvrir", command=self.ouvrir) self.fichier.add_command(label="Fermer", command=self.fermer) self.fichier.add_command(label="Enregistrer", command=self.enregistrer) self.fichier.add_separator() self.fichier.add_command(label="Quitter", command=self.quitter) # creation du menu "Aide" self.aide = Tkinter.Menu(self.barremenu, tearoff=0, font=policemenu) self.barremenu.add_cascade(label="Aide",menu=self.aide) self.aide.add_command(label="Manuel", command = self.manuel) self.aide.add_command(label="A propos", command = self.apropos) # afficher le menu self.master.config(menu=self.barremenu) def ouvrir(self): print "Ouvrir" def fermer(self): print "fermer" def enregistrer(self): print "enregistrer" def quitter(self): self.master.destroy() def manuel(self): print "manuel" def apropos(self): print "apropos" ############################################################################# fen=Tkinter.Tk() fen.title("Ma fenêtre") app=Application(fen) fen.geometry("%dx%d%+d%+d" % (300,300,100,100)) fen.mainloop()
On peut changer la couleur de la police, la couleur de fond ainsi que la couleur de la barre de sélection au passage de la souris. Cela ne concerne pas les items de la barre de menu eux-même, mais des fenêtres d'items qui sont appelées par eux.
La couleur peut être définie par les noms habituels ('red' = rouge, 'blue' = bleu, etc…), ou par des valeurs hexadécimales.
Comme pour le changement de police, il faut provoquer la modification pour chacun des items de la barre de menu.
#!/usr/bin/python # -*- coding: utf-8 -*- import Tkinter class Application(Tkinter.Frame): def __init__(self, master=None): Tkinter.Frame.__init__(self, master, background="grey") # creation de la barre de menu: self.barremenu = Tkinter.Menu(self.master) # creation du menu "Fichier" self.fichier = Tkinter.Menu(self.barremenu, tearoff=0, bg='yellow', fg='green', activebackground='red', activeforeground='yellow') self.barremenu.add_cascade(label="Fichier",menu=self.fichier) self.fichier.add_command(label="Ouvrir", command=self.ouvrir) self.fichier.add_command(label="Fermer", command=self.fermer) self.fichier.add_command(label="Enregistrer", command=self.enregistrer) self.fichier.add_separator() self.fichier.add_command(label="Quitter", command=self.quitter) # creation du menu "Aide" self.aide = Tkinter.Menu(self.barremenu, tearoff=0, bg='yellow', fg='green', activebackground='red', activeforeground='yellow') self.barremenu.add_cascade(label="Aide",menu=self.aide) self.aide.add_command(label="Manuel", command = self.manuel) self.aide.add_command(label="A propos", command = self.apropos) # afficher le menu self.master.config(menu=self.barremenu) def ouvrir(self): print "Ouvrir" def fermer(self): print "fermer" def enregistrer(self): print "enregistrer" def quitter(self): self.master.destroy() def manuel(self): print "manuel" def apropos(self): print "apropos" ############################################################################# fen=Tkinter.Tk() fen.title("Ma fenêtre") app=Application(fen) fen.geometry("%dx%d%+d%+d" % (300,300,100,100)) fen.mainloop()