Outils pour utilisateurs

Outils du site


issue52:tutopython

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
issue52:tutopython [2011/09/08 21:46] fredphil91issue52:tutopython [2011/11/02 15:29] (Version actuelle) – corrections mineurs de participa passé ald infinitif et singulier avec s marchois
Ligne 6: Ligne 6:
 Radiobuttons are considered a one of many type selection widget. It also has two options, on and off. However, they are grouped together to provide a set of options that logically can have only one selection. You can have multiple groups of Radiobuttons that, if properly programmed, won't interact with each other.** Radiobuttons are considered a one of many type selection widget. It also has two options, on and off. However, they are grouped together to provide a set of options that logically can have only one selection. You can have multiple groups of Radiobuttons that, if properly programmed, won't interact with each other.**
  
-Le mois dernier, nous avons parlé de TkInter et de quatre des widgets disponibles : la fenêtre principale, les fenêtres, les boutons et les étiquettes (ou labels). Je vous ai également dit le mois dernier que je parlerai de la façon d'avoir un widget autre que le widget de premier niveau comme parent. +Le mois dernier, nous avons parlé de TkInter et de quatre des widgets disponibles : la fenêtre principale, les fenêtres, les boutons et les étiquettes (ou labels). Je vous ai également dit le mois dernier que je parlerais de la façon d'avoir un widget autre que le widget de premier niveau comme parent. 
-Aussi, ce mois-ci, nous allons approfondir les fenêtres, les boutons et les étiquettes, et introduire les cases à cocher, les boutons radio, les zones de texte (ou widgets Entry), les listes avec une barre de défilement verticale les fenêtres de messages. Avant de commencer, examinons certains de ces widgets.+Aussi, ce mois-ci, nous allons approfondir les fenêtres, les boutons et les étiquettes, et introduire les cases à cocher, les boutons radio, les zones de texte (ou widgets Entry), les listes avec une barre de défilement verticale (ListBox) et les fenêtres de message. Avant de commencer, examinons certains de ces widgets.
  
-Les cases à cocher servent à faire plusieurs choix parmi plusieurs propositions et ont deux états : cochée ou non cochée, ou on pourrait dire aussi oui ou non. Elles sont généralement utilisées pour fournir une série d'options, et quelques-unes, plusieurs ou toutes ces options peuvent être sélectionnées. Vous pouvez définir un événement pour vous informer quand la case a été cochée ou décochée, ou tout simplement pour interroger la valeur du widget à tout moment.+Les cases à cocher servent à faire plusieurs choix parmi plusieurs propositions et ont deux états : cochée ou non cochée, ou on pourrait dire aussi oui ou non. Elles sont généralement utilisées pour fournir une série d'options où une, quelques-unes ou toutes peuvent être sélectionnées. Vous pouvez définir un événement pour vous informer quand la case a changé d'état ou tout simplement pour interroger la valeur du widget à tout moment.
  
-Les boutons radio servent à faire un choix parmi plusieurs propositions. Ils ont aussi deux états, oui ou non. Cependant, ils sont groupés ensemble pour fournir un groupe d'options dont une seule peut-être choisie. Vous pouvez avoir plusieurs groupes de boutons radio qui, s'ils sont bien programmés, n'interféreront pas l'un avec l'autre.+Les boutons radio servent à faire un choix parmi plusieurs propositions. Ils ont aussi deux états, oui ou non. Cependant, ils sont groupés ensembles pour fournir un groupe d'options dont une seule peut être choisie. Vous pouvez avoir plusieurs groupes de boutons radio qui, s'ils sont bien programmés, n'interféreront pas entre eux.
  
 **A Listbox provides a list of items for the user to select from. Most times, you want the user to select only one of the items at a time, but there can be occasions that you will allow the user to select multiple items. A scroll bar can be placed either horizontally or vertically to allow the user to easily look through all the items available. **A Listbox provides a list of items for the user to select from. Most times, you want the user to select only one of the items at a time, but there can be occasions that you will allow the user to select multiple items. A scroll bar can be placed either horizontally or vertically to allow the user to easily look through all the items available.
Ligne 25: Ligne 25:
    7. The final frame will have a series of buttons that will call various types of message boxes.**    7. The final frame will have a series of buttons that will call various types of message boxes.**
  
 +Une ListBox fournit une liste d'éléments parmi lesquels l'utilisateur peut sélectionner. La plupart du temps, vous voulez que l'utilisateur sélectionne un seul des éléments à la fois, mais, parfois, vous pouvez vouloir permettre à l'utilisateur de sélectionner plusieurs éléments. Une barre de défilement peut être placée horizontalement ou verticalement afin de permettre à l'utilisateur de parcourir facilement tous les éléments disponibles.
  
 +Notre projet consistera en une fenêtre principale et sept cadres principaux qui regrouperont visuellement nos ensembles de widgets :
 +
 +    1. Le premier cadre sera très basique : il contient simplement différents labels, montrant les différentes options de mise en relief.
 +    2. Le second -plutôt simple également- contiendra des boutons qui utilisent ces mêmes options de relief.
 +    3. Dans ce cadre, nous aurons deux cases à cocher et un bouton qui inverse leur état par programmation. Elles renverront cet état (1 ou 0) à la fenêtre du terminal lorsqu'elles sont cliquées ou que le bouton est actionné.
 +    4. Ensuite, nous aurons deux groupes indépendants de trois boutons radio envoyant chacun un message à la fenêtre du terminal lorsqu'on clique dessus.
 +    5. Celui-ci contient des champs de texte qui ne sont pas nouveaux pour vous, mais il y a aussi un bouton pour activer et désactiver l'un d'eux. Lorsqu'il est désactivé, aucune saisie ne peut y être faite.
 +    6. Celui-ci contient une liste avec une barre de défilement verticale qui envoie un message au terminal à chaque fois qu'un élément est sélectionné ; il aura deux boutons. Un bouton va effacer la zone de liste et l'autre la remplira avec des valeurs fictives.
 +    7. Le dernier cadre contient une série de boutons qui appellent les différents types de boîtes de message.
  
 **So now, we'll start our project. Let's name it “widgetdemo1.py”. Be sure to save it because we will be writing our project in little pieces, and build on them to make our full app. Each piece revolves around one of the frames. You'll notice that I'm including a number of comments as we go, so you can refer back to what's happening. Here's the first few lines... **So now, we'll start our project. Let's name it “widgetdemo1.py”. Be sure to save it because we will be writing our project in little pieces, and build on them to make our full app. Each piece revolves around one of the frames. You'll notice that I'm including a number of comments as we go, so you can refer back to what's happening. Here's the first few lines...
Ligne 39: Ligne 49:
        self.PlaceWidgets(f)**        self.PlaceWidgets(f)**
  
-**The first two lines (comments) are the name of the application and what we are concentrating on in this partLine three is our import statementThen we define our classThe next line starts our __init__ routinewhich you all should be familiar with by now, but, if you are just joining us, it's the code that gets run when we instantiate the routine in the main portion of the programWe are passing it the Toplevel or root windowwhich comes in as master hereThe last three lines (so far), call three different routinesThe first (DefineVars) will set up various variables we'll need as we goThe next (BuildWidgets) will be where we define our widgets, and the last (PlaceWidgets) is where we actually place the widgets into the root window. As we did last time, we'll be using the grid geometry manager. Notice that BuildWidgets will return the object “f” (which is our root window), and we'll pass that along to the PlaceWidgets routine.**+Bon, maintenant nous allons commencer notre projetNommons-le « widgetdemo1.py »Assurez-vous de le sauvegardercar nous allons écrire notre projet par petits morceaux et construire notre application complète petit à petit. Chaque morceau tourne autour de l'un des cadresVous remarquerez que j'intègre un certain nombre de commentaires au fur et à mesurepour que vous puissiez suivre ce qui se passeVoici les premières lignes...
  
 +# widgetdemo1.py
 +# Labels
 +from Tkinter import *
 +
 +class Demo:
 +    def __init__(self,principale):
 +        self.DefinirVariables()
 +        f = self.ConstruireWidgets(principale)
 +        self.PlacerWidgets(f)
 +
 +**The first two lines (comments) are the name of the application and what we are concentrating on in this part. Line three is our import statement. Then we define our class. The next line starts our <nowiki>__init__</nowiki> routine, which you all should be familiar with by now, but, if you are just joining us, it's the code that gets run when we instantiate the routine in the main portion of the program. We are passing it the Toplevel or root window, which comes in as master here. The last three lines (so far), call three different routines. The first (DefineVars) will set up various variables we'll need as we go. The next (BuildWidgets) will be where we define our widgets, and the last (PlaceWidgets) is where we actually place the widgets into the root window. As we did last time, we'll be using the grid geometry manager. Notice that BuildWidgets will return the object “f” (which is our root window), and we'll pass that along to the PlaceWidgets routine.**
  
 +Les deux premières lignes (commentaires) sont le nom de l'application et le thème de cette partie. La ligne trois est notre déclaration d'importation. Ensuite, nous définissons notre classe. La ligne suivante commence notre routine <nowiki>__init__</nowiki>, avec laquelle vous devriez tous être familiers maintenant ; mais si vous venez juste de nous rejoindre, c'est le code qui est exécuté quand on instancie la routine dans la partie principale du programme. Nous lui passons la fenêtre racine (ou toplevel), qui s'appelle « principale » ici. Les trois dernières lignes (jusqu'à présent) appellent trois routines différentes. La première (DefinirVariables) réglera différentes variables dont nous aurons besoin plus tard. La suivante (ConstruireWidgets) sera l'endroit où nous définissons nos widgets, et la dernière (PlacerWidgets) est celle où nous allons placer les widgets dans la fenêtre racine. Comme nous l'avons fait la dernière fois, nous allons utiliser le gestionnaire de géométrie « grille ». Notez que ConstruireWidgets retournera l'objet « f » (qui est notre fenêtre racine) que nous passerons à la routine PlacerWidgets.
  
 **   def BuildWidgets(self,master): **   def BuildWidgets(self,master):
Ligne 61: Ligne 83:
        return frame**        return frame**
  
 +  def ConstruireWidgets(self,principale): 
 +        # definition de nos widgets 
 +        fenetre = Frame(principale) 
 +        # labels (ou etiquettes) 
 +        self.cadreLabels = Frame(fenetre,relief = SUNKEN,padx = 3, pady = 3, 
 +                                   borderwidth = 2, width = 500) 
 +        self.lbl1 = Label(self.cadreLabels,text="Label plat",relief = FLAT, 
 +                                   width = 13,borderwidth = 2) 
 +        self.lbl2 = Label(self.cadreLabels,text="Label creux", relief = SUNKEN, 
 +                                   width = 13, borderwidth = 2) 
 +        self.lbl3 = Label(self.cadreLabels,text="Label arete", relief = RIDGE, width = 13, 
 +                          borderwidth = 2) 
 +        self.lbl4 = Label(self.cadreLabels,text="Label souleve", relief = RAISED, 
 +                          width = 13, borderwidth = 2) 
 +        self.lbl5 = Label(self.cadreLabels,text="Label rainure", relief = GROOVE, 
 +                          width = 13, borderwidth = 2) 
 +        return fenetre
  
 **This is our BuildWidgets routine. Each of the lines that start with “self.” have been split for two reasons. First, it's good practice to keep the line length to 80 characters or less. Secondly, it makes it easier on our wonderful editor. You can do two things. One, just make each line long, or keep it as is. Python lets us split lines as long as they are within parentheses or brackets. As I said earlier, we are defining the widgets before we place them in the grid. You'll notice when we do the next routine, that we can also define a widget at the time we place it in the grid, but defining it before we put it in the grid in a routine like this makes it easier to keep track of everything, since we are doing (most of) the definitions in this routine. **This is our BuildWidgets routine. Each of the lines that start with “self.” have been split for two reasons. First, it's good practice to keep the line length to 80 characters or less. Secondly, it makes it easier on our wonderful editor. You can do two things. One, just make each line long, or keep it as is. Python lets us split lines as long as they are within parentheses or brackets. As I said earlier, we are defining the widgets before we place them in the grid. You'll notice when we do the next routine, that we can also define a widget at the time we place it in the grid, but defining it before we put it in the grid in a routine like this makes it easier to keep track of everything, since we are doing (most of) the definitions in this routine.
Ligne 67: Ligne 105:
 So, first we define our master frame. This is where we will be putting the rest of our widgets. Next, we define a child (of the master frame) frame that will hold five labels, and call it lblframe. We set the various attributes of the frame here. We set the relief to 'SUNKEN', a padding of 3 pixels on left and right (padx), and 3 pixels on the top and bottom (pady). We also set the borderwidth to 2 pixels so that its sunken relief is noticeable. By default, the borderwidth is set to 0, and the effect of being sunken won't be noticed. Finally, we set the total width of the frame to 500 pixels.** So, first we define our master frame. This is where we will be putting the rest of our widgets. Next, we define a child (of the master frame) frame that will hold five labels, and call it lblframe. We set the various attributes of the frame here. We set the relief to 'SUNKEN', a padding of 3 pixels on left and right (padx), and 3 pixels on the top and bottom (pady). We also set the borderwidth to 2 pixels so that its sunken relief is noticeable. By default, the borderwidth is set to 0, and the effect of being sunken won't be noticed. Finally, we set the total width of the frame to 500 pixels.**
  
 +Voici notre routine ConstruireWidgets. Les lignes qui commence par « self. » ont été coupées pour deux raisons. Tout d'abord, c'est une bonne pratique de garder la longueur de la ligne à moins de 80 caractères. Deuxièmement, cela facilite les choses pour notre merveilleux éditeur. Vous avez deux possibilités : soit écrire des lignes longues, soit les garder comme ça. Python nous permet de couper les lignes tant qu'elles sont entre des parenthèses ou des crochets. Comme je l'ai dit précédemment, nous définissons les widgets avant de les placer dans la grille. Quand nous écrirons la routine suivante, vous remarquerez que nous pouvons aussi en définir un au moment où nous le plaçons ; mais le faire dans une routine séparée clarifie les choses, puisque nous y regroupons la plupart des définitions.
  
 +Nous définissons donc d'abord notre fenêtre principale. C'est là que nous mettrons le reste de nos widgets. Ensuite, nous définissons une cadre fils (de la fenêtre principale), qui contiendra cinq étiquettes, et l'appelons cadreLabels. Nous réglons les différents attributs du cadre ici. Nous réglons le relief à « en creux » (« SUNKEN »), une marge de 3 pixels à gauche et à droite (padx), et de 3 pixels en haut et en bas (pady). Nous avons également mis la largeur de bordure à 2 pixels de telle sorte que son relief en creux soit perceptible. Par défaut, la largeur de bordure vaut 0 et l'effet de creux ne serait pas visible. Enfin, nous avons mis la largeur totale du cadre à 500 pixels.
  
-**Next, we define each label widget that we will use. We set the parent as self.lblframe, and not to frame. This way all the labels are children of lblframe, and lblframe is a child of frame. Notice that each definition is pretty much the same for all five of the labels except the name of the widget (lbl1, lbl2, etc), the text, and the relief or visual effect. Finally, we return the frame back to the calling routine (__init__).+**Next, we define each label widget that we will use. We set the parent as self.lblframe, and not to frame. This way all the labels are children of lblframe, and lblframe is a child of frame. Notice that each definition is pretty much the same for all five of the labels except the name of the widget (lbl1, lbl2, etc), the text, and the relief or visual effect. Finally, we return the frame back to the calling routine (<nowiki>__init__</nowiki>).
  
 Here's our PlaceWidgets routine... Here's our PlaceWidgets routine...
Ligne 87: Ligne 127:
        self.lbl5.grid(column = 5, row = 0, padx = 3, pady = 5)**        self.lbl5.grid(column = 5, row = 0, padx = 3, pady = 5)**
  
 +Ensuite, nous définissons chaque widget étiquette que nous allons utiliser. Nous fixons le parent à self.cadreLabels, et non pas fenetre. De cette façon, toutes les étiquettes sont des enfants de cadreLabels qui lui-même est un enfant de fenetre. Remarquez que chaque définition est à peu près semblable pour l'ensemble des cinq étiquettes, sauf le nom du widget (lbl1, lbl2, etc), le texte et le relief ou effet visuel. Enfin, nous retournons la fenêtre à la routine appelante (<nowiki>__init__</ nowiki>).
  
 +Voici notre routine PlacerWidgets...
 +
 +    def PlacerWidgets(self, principale):
 +        fenetre = principale
 +        # place les widgets
 +        fenetre.grid(column = 0, row = 0)
 +        # place les labels
 +        self.cadreLabels.grid(column = 0, row = 1, padx = 5, pady = 5,
 +                                columnspan = 5,sticky='WE')
 +        l = Label(self.cadreLabels,text='Labels |',width=15,
 +                  anchor='e').grid(column=0,row=0)
 +        self.lbl1.grid(column = 1, row = 0, padx = 3, pady = 5)
 +        self.lbl2.grid(column = 2, row = 0, padx = 3, pady = 5)
 +        self.lbl3.grid(column = 3, row = 0, padx = 3, pady = 5)
 +        self.lbl4.grid(column = 4, row = 0, padx = 3, pady = 5)
 +        self.lbl5.grid(column = 5, row = 0, padx = 3, pady = 5)
  
 **We get the frame object in as a parameter called master. We assign that to 'frame' to simply be consistent with what we did in the BuildWidgets routine. Next, we set our main grid up (frame.grid(column = 0, row = 0)). If we don't do this, nothing works correctly. Then we start putting our widgets into the grid locations. First we put the frame (lblframe) that holds all our labels, and set its attributes. We put it in column 0, row 1, set the padding to 5 pixels on all sides, tell it to span 5 columns (left and right), and finally use the “sticky” attribute to force the frame to expand fully to the left and right (“WE”, or West and East). Now comes the part that sort of breaks the rule that I told you about. We are placing a label as the first widget in the frame, but we didn't define it ahead of time. We define it now. We set the parent to lblframe, just like the other labels. We set the text to “Labels |”, the width to 15, and the anchor to east ('e'). If you remember from last time, using the anchor attribute, we can set where in the widget the text will display. In this case, it's along the right border. Now the fun part. Here we define the grid location (and any other grid attributes we need to), simply by appending “.grid” at the end of the label definition. **We get the frame object in as a parameter called master. We assign that to 'frame' to simply be consistent with what we did in the BuildWidgets routine. Next, we set our main grid up (frame.grid(column = 0, row = 0)). If we don't do this, nothing works correctly. Then we start putting our widgets into the grid locations. First we put the frame (lblframe) that holds all our labels, and set its attributes. We put it in column 0, row 1, set the padding to 5 pixels on all sides, tell it to span 5 columns (left and right), and finally use the “sticky” attribute to force the frame to expand fully to the left and right (“WE”, or West and East). Now comes the part that sort of breaks the rule that I told you about. We are placing a label as the first widget in the frame, but we didn't define it ahead of time. We define it now. We set the parent to lblframe, just like the other labels. We set the text to “Labels |”, the width to 15, and the anchor to east ('e'). If you remember from last time, using the anchor attribute, we can set where in the widget the text will display. In this case, it's along the right border. Now the fun part. Here we define the grid location (and any other grid attributes we need to), simply by appending “.grid” at the end of the label definition.
Ligne 93: Ligne 150:
 Next, we lay out all of our other labels in the grid - starting at column 1, row 0.** Next, we lay out all of our other labels in the grid - starting at column 1, row 0.**
  
 +Nous récupérons l'objet fenêtre en tant que paramètre appelé « principale ». Nous l'assignons à « fenetre » simplement pour être cohérent avec ce que nous avons fait dans la routine ConstruireWidgets. Ensuite, nous mettons en place la grille principale (fenetre.grid (column=0, row=0)). Si nous ne faisons pas cela, rien ne fonctionnera correctement. Ensuite, nous commençons à mettre nos widgets dans les emplacements de la grille. D'abord nous mettons le cadre (cadreLabels) qui contient toutes nos étiquettes et définissons ses attributs. Nous le plaçons colonne 0, ligne 1, réglons la marge à 5 pixels sur tous les côtés, lui disons de s'étaler sur 5 colonnes (à droite et à gauche), et enfin utilisons l'attribut « sticky » [Ndt : collant] pour forcer la fenêtre à s'étendre complètement à gauche et à droite (« WE » pour Ouest et Est). Maintenant vient la partie qui casse la règle dont je vous ai parlé. Nous mettons une étiquette comme premier widget dans la fenêtre, mais nous ne l'avons pas défini à l'avance : nous le faisons maintenant. Nous avons mis comme parent cadreLabels, tout comme les autres étiquettes. Nous réglons le texte à « Labels | », la largeur à 15, et l'ancrage à Est ('e'). Si vous vous souvenez de la dernière fois, en utilisant l'attribut d'ancrage, nous pouvons choisir où le texte s'affiche dans le widget. Dans ce cas, c'est le long du bord droit. Maintenant la partie amusante. Ici, nous définissons l'emplacement de la grille (et tous les autres attributs de la grille dont nous avons besoin), simplement en ajoutant « .grid » à la fin de la définition des étiquettes.
  
 +Ensuite, nous plaçons toutes nos autres étiquettes dans la grille, à partir de la colonne 1, ligne 0.
  
 **Here is our DefineVars routine. Notice that we simply use the pass statement for now. We'll be filling it in later on, and we don't need it for this part: **Here is our DefineVars routine. Notice that we simply use the pass statement for now. We'll be filling it in later on, and we don't need it for this part:
Ligne 108: Ligne 167:
 root.mainloop()** root.mainloop()**
  
 +Voici notre routine DefinirVariables. Notez que nous utilisons simplement l'instruction pass pour l'instant. Nous la remplirons plus tard, car nous n'en avons pas besoin pour cette partie :
 +    def DefinirVariables(self):
 +        # definit nos ressources
 +        pass
  
 +Et enfin nous plaçons notre code pour la routine principale :
 +  racine = Tk()
 +  racine.geometry('750x40+150+150')
 +  racine.title("Demo Widget 1")
 +  demo = Demo(racine)
 +  
 +  racine.mainloop()
  
 **First, we instantiate an instance of Tk. Thern we set the size of the main window to 750 pixels wide by 40 pixels high, and locate it at 150 pixels from the left and top of the screen. Then we set the title of the window and instantiate our Demo object, and finally call the Tk mainloop. **First, we instantiate an instance of Tk. Thern we set the size of the main window to 750 pixels wide by 40 pixels high, and locate it at 150 pixels from the left and top of the screen. Then we set the title of the window and instantiate our Demo object, and finally call the Tk mainloop.
Ligne 116: Ligne 186:
 Now save what you have as widgetdemo1a.py, and let's add some buttons. Since we built our base program to be added to, we'll simply add the parts that apply. Let's start with the BuildWidgets routine. After the labels definitions, and before the “return frame” line, add the following...** Now save what you have as widgetdemo1a.py, and let's add some buttons. Since we built our base program to be added to, we'll simply add the parts that apply. Let's start with the BuildWidgets routine. After the labels definitions, and before the “return frame” line, add the following...**
  
 +D'abord, on crée une instance de Tk. Puis nous définissons la taille de la fenêtre principale à 750 pixels de large sur 40 pixels de haut et la localisons à 150 pixels de la gauche et du haut de l'écran. Puis nous réglons le titre de la fenêtre et instancions notre objet Demo et, enfin, appelons la boucle principale de Tk.
 +
 +Essayez. Vous devriez voir les cinq étiquettes ainsi que l'étiquette de « dernière minute » avec divers effets magnifiques.
 +
 +Les boutons
  
 +Maintenant, enregistrez ce que vous avez en tant que widgetdemo1a.py et nous ajoutons quelques boutons. Puisque nous avons construit notre programme de base ainsi, nous allons simplement pouvoir y ajouter les parties qui manquent. Commençons par la routine ConstruireWidgets. Après les définitions des étiquettes, et avant le « return fenetre », ajoutez ce qui suit...
  
 **       # Buttons **       # Buttons
Ligne 137: Ligne 213:
        self.btn5.bind('<ButtonRelease-1>',lambda e: self.BtnCallback(5))**        self.btn5.bind('<ButtonRelease-1>',lambda e: self.BtnCallback(5))**
  
 +        # boutons 
 +        self.cadreBoutons = Frame(fenetre,relief = SUNKEN,padx = 3, 
 +                                    pady = 3, borderwidth = 2, width = 500) 
 +        self.btn1 = Button(self.cadreBoutons,text="Bouton plat", 
 +                           relief = FLAT, borderwidth = 2) 
 +        self.btn2 = Button(self.cadreBoutons,text="Bouton creux", 
 +                           relief = SUNKEN, borderwidth = 2) 
 +        self.btn3 = Button(self.cadreBoutons,text="Bouton arete", 
 +                           relief = RIDGE, borderwidth = 2) 
 +        self.btn4 = Button(self.cadreBoutons,text="Bouton souleve", 
 +                           relief = RAISED, borderwidth = 2) 
 +        self.btn5 = Button(self.cadreBoutons,text="Bouton rainure", 
 +                           relief = GROOVE, borderwidth = 2) 
 +        self.btn1.bind('<ButtonRelease-1>',lambda e: self.clicBouton(1)) 
 +        self.btn2.bind('<ButtonRelease-1>',lambda e: self.clicBouton(2)) 
 +        self.btn3.bind('<ButtonRelease-1>',lambda e: self.clicBouton(3)) 
 +        self.btn4.bind('<ButtonRelease-1>',lambda e: self.clicBouton(4)) 
 +        self.btn5.bind('<ButtonRelease-1>',lambda e: self.clicBouton(5))
  
 **Nothing really new here. We've defined the buttons, with their attributes, and set their callbacks via the .bind configuration. Notice that we are using lambda to send the values 1 through 5 based on which button is clicked. In the callback, we'll use that so we know which button we are dealing with. Now we'll work in the PlaceWidgets routine. Put the following code right after the last label placement: **Nothing really new here. We've defined the buttons, with their attributes, and set their callbacks via the .bind configuration. Notice that we are using lambda to send the values 1 through 5 based on which button is clicked. In the callback, we'll use that so we know which button we are dealing with. Now we'll work in the PlaceWidgets routine. Put the following code right after the last label placement:
Ligne 151: Ligne 244:
        self.btn5.grid(column = 5, row = 0, padx = 3, pady = 3)**        self.btn5.grid(column = 5, row = 0, padx = 3, pady = 3)**
  
 +Rien de bien nouveau ici. Nous avons défini les boutons avec leurs attributs et avons fixé leurs fonctions de rappel avec un « .bind ». Notez que nous utilisons lambda pour envoyer les valeurs 1 à 5 suivant le bouton sur lequel on clique. Dans la fonction de rappel, nous allons utiliser cela afin de savoir quel bouton on doit gérer. Maintenant, nous allons travailler dans la routine PlacerWidgets. Placez le code suivant juste après l'emplacement de la dernière étiquette : 
 +        # place les boutons 
 +        self.cadreBoutons.grid(column=0, row = 2, padx = 5, 
 +                                 pady = 5, columnspan = 5,sticky = 'WE'
 +        l = Label(self.cadreBoutons,text='Boutons |',width=15, 
 +                  anchor='e').grid(column=0,row=0) 
 +        self.btn1.grid(column = 1, row = 0, padx = 3, pady = 3) 
 +        self.btn2.grid(column = 2, row = 0, padx = 3, pady = 3) 
 +        self.btn3.grid(column = 3, row = 0, padx = 3, pady = 3) 
 +        self.btn4.grid(column = 4, row = 0, padx = 3, pady = 3) 
 +        self.btn5.grid(column = 5, row = 0, padx = 3, pady = 3)     
  
 **Once again, nothing really new here, so we'll move on. Here's our callback routine. Put it after the DefineVars routine: **Once again, nothing really new here, so we'll move on. Here's our callback routine. Put it after the DefineVars routine:
Ligne 166: Ligne 269:
            print("Groove Button Clicked...")**            print("Groove Button Clicked...")**
  
 +Une fois de plus, rien de vraiment nouveau ici, donc nous allons continuer. Voici notre routine de rappel. Placez-la après la routine DefinirVariables : 
 +    def clicBouton(self,val): 
 +        if val == 1: 
 +            print("Clic bouton plat..."
 +        elif val == 2: 
 +            print("Clic bouton creux..."
 +        elif val == 3: 
 +            print("Clic bouton arete..."
 +        elif val == 4: 
 +            print("Clic bouton souleve..."
 +        elif val == 5: 
 +            print("Clic bouton rainure...")
  
 **Again, nothing really fancy here. We just use a series of IF/ELIF routines to print what button was clicked. The main thing to look at here (when we run the program) is that the sunken button doesn't “move” when you click on it. You would not usually use the sunken relief unless you were making a button that stays “down” when you click it. Finally, we need to tweak the geometry statement to support the extra widgets we put in: **Again, nothing really fancy here. We just use a series of IF/ELIF routines to print what button was clicked. The main thing to look at here (when we run the program) is that the sunken button doesn't “move” when you click on it. You would not usually use the sunken relief unless you were making a button that stays “down” when you click it. Finally, we need to tweak the geometry statement to support the extra widgets we put in:
Ligne 175: Ligne 289:
 Now save this as widgetdemo1b.py, and we'll move on to checkboxes.** Now save this as widgetdemo1b.py, and we'll move on to checkboxes.**
  
 +Encore une fois, rien de vraiment sensationnel ici. Nous utilisons simplement une série de routines IF/ELIF pour afficher quel bouton a été cliqué. La principale chose à regarder ici (lorsque nous exécutons le programme) est que le bouton « en creux » ne bouge pas lorsqu'on clique dessus. En général on n'utilise pas le relief « en creux », sauf si vous souhaitez un bouton qui reste enfoncé lorsque vous cliquez dessus. Enfin, nous avons besoin d'ajuster la déclaration de la géométrie à cause des widgets supplémentaires que nous avons ajoutés :
 +  root.geometry ('750x110+150+150')
 +
 +Ok. C'est terminé pour celui-ci. Enregistrez-le et lancez-le.
  
 +Maintenant sauvegardez ceci comme widgetdemo1b.py et nous allons passer aux cases à cocher.
  
 **Checkboxes **Checkboxes
 As I said earlier, this part of the demo has a normal button and two checkboxes. The first checkbox is what you would normally expect a checkbox to look like. The second is more like a “sticky” button - when it's not selected (or checked), it looks like a normal button. When you select it, it looks like a button that is stuck down. We can do this by simply setting the indicatoron attribute to False. The “normal” button will toggle the checkboxes from checked to unchecked, and vice versa, each time you click the button. We get to do this programmatically by calling the .toggle method attached to the checkbox. We bind the left mouse button click event (button release) to a function so we can send a message (in this case) to the terminal. In addition to all of this, we are setting two variables (one for each of the checkboxes) that we can query at any time. In this case, each time the checkbox is clicked we query this value and print it. Pay attention to the variable portion of the code. It is used in many widgets.** As I said earlier, this part of the demo has a normal button and two checkboxes. The first checkbox is what you would normally expect a checkbox to look like. The second is more like a “sticky” button - when it's not selected (or checked), it looks like a normal button. When you select it, it looks like a button that is stuck down. We can do this by simply setting the indicatoron attribute to False. The “normal” button will toggle the checkboxes from checked to unchecked, and vice versa, each time you click the button. We get to do this programmatically by calling the .toggle method attached to the checkbox. We bind the left mouse button click event (button release) to a function so we can send a message (in this case) to the terminal. In addition to all of this, we are setting two variables (one for each of the checkboxes) that we can query at any time. In this case, each time the checkbox is clicked we query this value and print it. Pay attention to the variable portion of the code. It is used in many widgets.**
  
 +Les cases à cocher
  
 +Comme je l'ai dit précédemment, cette partie de la démo a un bouton normal et deux cases à cocher. L'apparence de la première case est celle à laquelle vous vous attendez normalement. La seconde est plus comme un « bouton collant » - quand elle n'est pas sélectionnée (ou cochée)??, elle ressemble à un bouton normal. Lorsque vous la sélectionnez, elle ressemble à un bouton qui reste enfoncé. Nous pouvons faire cela simplement en définissant l'attribut indicatoron à False. Le bouton « normal » permet de basculer les cases de « cochées » à « décochées » et vice versa, à chaque fois que l'on clique dessus. Nous arrivons à programmer cela en appelant la méthode .toggle liée à la case à cocher. Nous relions l'événement clic gauche de la souris (lorsque le bouton est relâché) à une fonction afin de pouvoir envoyer un message (dans notre cas) au terminal. En plus de tout cela, nous mettons en place deux variables (une pour chacune des cases à cocher) que l'on peut interroger à tout moment. Ici, nous interrogeons ces valeurs et les affichons à chaque fois qu'une case est cliquée. Faites attention à la partie variable du code : elle est utilisée dans de nombreux widgets.
  
 **Under the BuildWidget routine, after the button code we just put in and before the return statement, put the following code: **Under the BuildWidget routine, after the button code we just put in and before the return statement, put the following code:
Ligne 195: Ligne 316:
        self.btnToggleCB.bind('<ButtonRelease-1>',self.btnToggle)**        self.btnToggleCB.bind('<ButtonRelease-1>',self.btnToggle)**
  
 +Dans la routine ConstruireWidgets, après le code des boutons que nous venons d'ajouter et avant l'instruction de retour, placez le code suivant : 
 +        # checkbox (ou cases a cocher) 
 +        self.cadreCases = Frame(fenetre, relief = SUNKEN, padx = 3, pady = 3, 
 +                                  borderwidth = 2, width = 500) 
 +        self.chk1 = Checkbutton(self.cadreCases, text = "Case a cocher normale", 
 +                                variable=self.Chk1Val) 
 +        self.chk2 = Checkbutton(self.cadreCases, text = "Case a cocher", 
 +                                variable=self.Chk2Val,indicatoron = False) 
 +        self.chk1.bind('<ButtonRelease-1>',lambda e: self.clicCases(1)) 
 +        self.chk2.bind('<ButtonRelease-1>',lambda e: self.clicCases(2)) 
 +        self.btnInverserCases = Button(self.cadreCases,text="Inverser cases"
 +        self.btnInverserCases.bind('<ButtonRelease-1>',self.btnInverser)
  
 **Again, you have seen all of this before. We create the frame to hold our widgets. We set up a button and two check boxes. Let's place them now: **Again, you have seen all of this before. We create the frame to hold our widgets. We set up a button and two check boxes. Let's place them now:
Ligne 207: Ligne 339:
        self.chk2.grid(column = 3, row = 0, padx = 3, pady = 3)**        self.chk2.grid(column = 3, row = 0, padx = 3, pady = 3)**
  
 +Encore une fois, vous avez vu tout cela avant. Nous créons le cadre pour contenir nos widgets. Nous créons un bouton et deux cases à cocher. Plaçons-les maintenant : 
 +        # place les cases à cocher et le bouton d'inversion 
 +        self.cadreCases.grid(column = 0, row = 3, padx = 5, pady = 5, 
 +                               columnspan = 5,sticky = 'WE'
 +        l = Label(self.cadreCases,text='Cases à cocher |',width=15, 
 +                  anchor='e').grid(column=0,row=0) 
 +        self.btnInverserCases.grid(column = 1, row = 0, padx = 3, pady = 3)                    
 +        self.chk1.grid(column = 2, row = 0, padx = 3, pady = 3) 
 +        self.chk2.grid(column = 3, row = 0, padx = 3, pady = 3)
  
 **Now we define the two variables that we will use to monitor the value of each check box. Under DefineVars, comment out the pass statement, and add this... **Now we define the two variables that we will use to monitor the value of each check box. Under DefineVars, comment out the pass statement, and add this...
Ligne 226: Ligne 366:
            print("Check box 2 value is {0}".format(self.Chk2Val.get()))**            print("Check box 2 value is {0}".format(self.Chk2Val.get()))**
  
 +Maintenant, nous définissons les deux variables que nous allons utiliser pour surveiller la valeur de chaque case à cocher. Sous DefinirVariables, commentez l'instruction pass et ajouter ceci...
 +        self.Chk1Val = IntVar ()
 +        self.Chk2Val = IntVar ()
  
 +Après la fonction de rappel des boutons, placez ce qui suit...
 +    def btnInverser(self,p1):
 +        self.chk1.toggle()
 +        self.chk2.toggle()
 +        print("Valeur de la case à cocher 1 : {0}".format(self.Chk1Val.get()))
 +        print("Valeur de la case à cocher 2 : {0}".format(self.Chk2Val.get()))        
  
 **And finally replace the geometry statement with this... **And finally replace the geometry statement with this...
Ligne 235: Ligne 384:
 If you are old enough to remember car radios with push buttons to select the station presets, you'll understand why these are called Radiobuttons. When using radiobuttons, the variable attribute is very important. This is what groups the radiobuttons together. In this demo, the first group of buttons is grouped by the variable named self.RBVal. The second is grouped by the variable self.RBValue2. We also need to set the value attribute at design time. This ensures that the buttons will return a value that makes sense whenever they are clicked.** If you are old enough to remember car radios with push buttons to select the station presets, you'll understand why these are called Radiobuttons. When using radiobuttons, the variable attribute is very important. This is what groups the radiobuttons together. In this demo, the first group of buttons is grouped by the variable named self.RBVal. The second is grouped by the variable self.RBValue2. We also need to set the value attribute at design time. This ensures that the buttons will return a value that makes sense whenever they are clicked.**
  
 +Et enfin remplacez l'instruction de géométrie par ceci...
 +  root.geometry ('750x170+150+150')
 +
 +Enregistrez et exécutez. Enregistrez-le comme widgetdemo1c.py et continuons avec les boutons radio.
 +
 +Les boutons radio
  
 +Si vous êtes assez vieux pour vous souvenir des autoradios avec boutons poussoirs pour sélectionner les stations préréglées, vous comprendrez pourquoi on appelle cela des boutons radio. Lorsque vous utilisez des boutons radio, l'attribut variable est très important. C'est ce qui regroupe les boutons radio ensemble. Dans cette démo, le premier groupe de boutons est formé avec la variable nommée self.RBVal. Le second groupe est formé par la variable self.RBVal2. Nous devons également définir l'attribut « value » au moment de la conception, afin de garantir que les boutons retourneront une valeur qui a du sens quand ils seront cliqués.
  
 **Back to BuildWidgets, and, just before the return statement, add the following code: **Back to BuildWidgets, and, just before the return statement, add the following code:
Ligne 253: Ligne 409:
        self.rb6.bind('<ButtonRelease-1>',lambda e: self.RBClick2())**        self.rb6.bind('<ButtonRelease-1>',lambda e: self.RBClick2())**
  
 +Retournez dans ConstruireWidgets, et ajoutez le code suivant juste avant l'instruction de retour : 
 +        # boutons radio 
 +        self.cadreBoutonsRadio = Frame(fenetre, relief = SUNKEN, padx = 3, pady = 3, borderwidth = 2, width = 500) 
 +        self.rb1 = Radiobutton(self.cadreBoutonsRadio, text = "Radio 1", variable = self.RBVal, value = 1) 
 +        self.rb2 = Radiobutton(self.cadreBoutonsRadio, text = "Radio 2", variable = self.RBVal, value = 2) 
 +        self.rb3 = Radiobutton(self.cadreBoutonsRadio, text = "Radio 3", variable = self.RBVal, value = 3) 
 +        self.rb1.bind('<ButtonRelease-1>',lambda e: self.clicBoutonRadio()) 
 +        self.rb2.bind('<ButtonRelease-1>',lambda e: self.clicBoutonRadio()) 
 +        self.rb3.bind('<ButtonRelease-1>',lambda e: self.clicBoutonRadio()) 
 +        self.rb4 = Radiobutton(self.cadreBoutonsRadio, text = "Radio 4", variable = self.RBVal2, value = "1-1"
 +        self.rb5 = Radiobutton(self.cadreBoutonsRadio, text = "Radio 5", variable = self.RBVal2, value = "1-2"
 +        self.rb6 = Radiobutton(self.cadreBoutonsRadio, text = "Radio 6", variable = self.RBVal2, value = "1-3"
 +        self.rb4.bind('<ButtonRelease-1>',lambda e: self.clicBoutonRadio2()) 
 +        self.rb5.bind('<ButtonRelease-1>',lambda e: self.clicBoutonRadio2()) 
 +        self.rb6.bind('<ButtonRelease-1>',lambda e: self.clicBoutonRadio2())                            
  
 **In PlaceWidgets, add this: **In PlaceWidgets, add this:
Ligne 273: Ligne 443:
        self.RBVal2.set("1-1")**        self.RBVal2.set("1-1")**
  
 +Ajoutez ceci dans PlacerWidgets : 
 +        # place les boutons radio et selectionne le premier 
 +        self.cadreBoutonsRadio.grid(column = 0, row = 4, padx = 5, pady = 5, columnspan = 5,sticky = 'WE'
 +        l = Label(self.cadreBoutonsRadio, 
 +                  text='Boutons radio |', 
 +                  width=15,anchor='e').grid(column=0,row=0) 
 +        self.rb1.grid(column = 2, row = 0, padx = 3, pady = 3, sticky = 'EW'
 +        self.rb2.grid(column = 3, row = 0, padx = 3, pady = 3, sticky = 'WE'
 +        self.rb3.grid(column = 4, row = 0, padx = 3, pady = 3, sticky = 'WE'
 +        self.RBVal.set("1"        
 +        l = Label(self.cadreBoutonsRadio,text='| Un autre groupe |', 
 +                  width = 15, 
 +                  anchor = 'e').grid(column = 5, row = 0) 
 +        self.rb4.grid(column = 6, row = 0) 
 +        self.rb5.grid(column = 7, row = 0) 
 +        self.rb6.grid(column = 8, row = 0) 
 +        self.RBVal2.set("1-1"            
  
 **One thing of note here. Notice the “last minute” label definitions in the PlaceWidget routine. These long lines are broken up to show how to use parens to allow our long lines to be formatted nicely in our code, and still function correctly. **One thing of note here. Notice the “last minute” label definitions in the PlaceWidget routine. These long lines are broken up to show how to use parens to allow our long lines to be formatted nicely in our code, and still function correctly.
Ligne 289: Ligne 475:
 root.geometry('750x220+150+150')** root.geometry('750x220+150+150')**
  
 +Une chose à noter ici. Remarquez les définitions de « dernière minute » pour les étiquettes dans la routine PlacerWidgets. Ces lignes longues sont coupées pour montrer comment utiliser les parenthèses pour permettre à nos longues lignes d'être formatées correctement dans notre code, et de fonctionner toujours correctement.
 +
 +Dans DefinirVariables, ajoutez :
 +        self.RBVal = IntVar ()
 +
 +Ajoutez les routines de clics :
 +    def clicBoutonRadio(self):
 +        print("Clic bouton radio - Valeur : {0}".format(self.RBVal.get()))        
 +    def clicBoutonRadio2(self):
 +        print("Clic bouton radio - Valeur : {0}".format(self.RBVal2.get()))             
  
 +et enfin modifiez à nouveau la géométrie comme ceci.
 +  root.geometry ('750x220+150+150')
  
 **Save the project as widgetdemo1d.py, and run it. Now, we'll start working on standard textboxes (or entry widgets). **Save the project as widgetdemo1d.py, and run it. Now, we'll start working on standard textboxes (or entry widgets).
Ligne 301: Ligne 499:
        self.btnDisable.bind('<ButtonRelease-1>', self.btnDisableClick)**        self.btnDisable.bind('<ButtonRelease-1>', self.btnDisableClick)**
  
 +Enregistrez le projet sous widgetdemo1d.py et exécutez-le. Maintenant, nous allons travailler sur les champs de texte standard (ou widgets de saisie).
  
 +Les champs de texte
 +
 +Encore une fois, nous avons déjà utilisé des champs de texte (ou widgets de saisie) dans diverses interfaces graphiques auparavant. Mais cette fois-ci, comme je l'ai dit précédemment, nous allons montrer comment empêcher l'utilisateur de faire des changements dans le champ texte en le désactivant. Cela s'avère utile si vous affichez certaines données et ne permettez à l'utilisateur de les modifier que lorsqu'il est dans le mode édition. À présent, vous devriez savoir que la première chose que nous devons faire est d'ajouter du code à la routine ConstruireWidgets :
 +        # champs de texte
 +        self.cadreChampsTexte = Frame(fenetre, relief = SUNKEN, padx = 3, pady = 3, borderwidth = 2, width = 500)
 +        self.txt1 = Entry(self.cadreChampsTexte, width = 10)
 +        self.txt2 = Entry(self.cadreChampsTexte, disabledbackground="#cccccc", width = 10)
 +        self.btnDesactiver = Button(self.cadreChampsTexte, text = "Activer/Desactiver")
 +        self.btnDesactiver.bind('<ButtonRelease-1>', self.clicBoutonDesactiver)
  
 **Next, add this code to the PlaceWidget routine: **Next, add this code to the PlaceWidget routine:
Ligne 314: Ligne 522:
       self.Disabled = False**       self.Disabled = False**
  
 +Ensuite, ajoutez le code à la routine PlacerWidgets :
 +        # place les champs de texte
 +        self.cadreChampsTexte.grid(column = 0, row = 5, padx = 5, pady = 5, columnspan = 5,sticky = 'WE')
 +        l = Label(self.cadreChampsTexte,text='Champs de texte |',width=15, anchor='e').grid(column=0,row=0)
 +        self.txt1.grid(column = 2, row = 0, padx = 3, pady = 3)
 +        self.txt2.grid(column = 3, row = 0, padx = 3, pady = 3)
 +        self.btnDesactiver.grid(column = 1, row = 0, padx = 3, pady = 3)
  
 +Ajoutez cette ligne en bas de la routine DefinirVariables :
 +      self.Disabled = False
  
 **Now, add the function that responds to the button click event: **Now, add the function that responds to the button click event:
Ligne 328: Ligne 545:
 root.geometry('750x270+150+150')** root.geometry('750x270+150+150')**
  
 +Maintenant ajoutez la fonction qui répond au clic sur le bouton :
 +    def clicBoutonDesactiver(self,p1):
 +        if self.Disabled == False:
 +            self.Disabled = True
 +            self.txt2.configure(state='disabled')
 +        else:
 +            self.Disabled = False
 +            self.txt2.configure(state='normal')
  
 +Reconfigurer les dimensions à :
 +root.geometry('750x270+150+150')
  
 **Save it as widgetdemo1d.py, and run it. **Save it as widgetdemo1d.py, and run it.
Ligne 347: Ligne 574:
            yscrollcommand = self.VScroll.set)**            yscrollcommand = self.VScroll.set)**
  
 +Sauvegardez-le sous le nom widgetdemo1d.py et exécutez-le.
 +
 +Les listes
 +
 +Ensuite nous allons travailler sur les listes. En commençant dans ConstruireWidgets, ajoutez le code suivant :
 +        # Données pour la liste
 +        self.cadreListe = Frame(fenetre,
 +                                  relief = SUNKEN,
 +                                  padx = 3, 
 +                                  pady = 3, 
 +                                  borderwidth = 2, 
 +                                  width = 500
 +        )
 +        # boite avec barre de défilement pour la liste
 +        self.defilementV = Scrollbar(self.cadreListe)
 +        self.liste = Listbox(self.cadreListe, 
 +                             height = 5,
 +                             yscrollcommand = self.defilementV.set)
  
 **    # default height is 10 **    # default height is 10
Ligne 367: Ligne 612:
        self.FillList()**        self.FillList()**
  
 +        # hauteur par defaut = 10 
 +        self.liste.bind('<<ListboxSelect>>',self.listeSelection) 
 +        self.defilementV.config(command = self.liste.yview) 
 +        self.btnEffacerListe = Button( 
 +             self.cadreListe, 
 +             text = "Effacer liste", 
 +             command = self.effacerListe, 
 +             width = 11 
 +        ) 
 +        self.btnRemplirListe = Button( 
 +             self.cadreListe, 
 +             text = "Remplir liste", 
 +             command = self.remplirListe,  
 +             width = 11 
 +        ) 
 +        # <<ListboxSelect>> est un evenement virtuel 
 +        # remplit la liste 
 +        self.remplirListe()
  
 **As usual, we create our frame. Then we create our vertical scroll bar. We do this before we create the list box, because we have to reference the scrollbar '.set' method. Notice the attribute 'height = 5'. This forces the listbox to show 5 items at a time. In the .bind statement, we use '<<ListboxSelect>>' as the event. It's called a virtual event, since it's not really an “official” event. **As usual, we create our frame. Then we create our vertical scroll bar. We do this before we create the list box, because we have to reference the scrollbar '.set' method. Notice the attribute 'height = 5'. This forces the listbox to show 5 items at a time. In the .bind statement, we use '<<ListboxSelect>>' as the event. It's called a virtual event, since it's not really an “official” event.
Ligne 380: Ligne 642:
        self.btnFillLBox.grid(column = 1, row = 1, padx = 5)**        self.btnFillLBox.grid(column = 1, row = 1, padx = 5)**
  
 +Comme d'habitude, nous créons notre cadre. Puis nous créons notre barre de défilement verticale. Nous le faisons avant de créer la liste parce que nous devons faire référence à la méthode « .set » de la barre de défilement. Remarquez l'attribut « height = 5 ». Cela force la liste à montrer 5 éléments à la fois. Dans la déclaration .bind, nous utilisons « <<ListboxSelect>> » comme événement. C'est ce qu'on appelle un événement virtuel, puisque ce n'est pas vraiment un événement « officiel ».
  
 +Maintenant, nous allons nous occuper du code supplémentaire dans la routine PlacerWidgets :
 +        # place la liste et les boutons associes
 +        self.cadreListe.grid(column = 0, row = 6, padx = 5, pady = 5, columnspan = 5,sticky = 'WE')
 +        l = Label(self.cadreListe,text='Liste |',width=15, anchor='e').grid(column=0,row=0,rowspan=2)
 +        self.liste.grid(column = 2, row = 0,rowspan=2)
 +        self.defilementV.grid(column = 3, row = 0,rowspan = 2, sticky = 'NSW')
 +        self.btnEffacerListe.grid(column = 1, row = 0, padx = 5)
 +        self.btnRemplirListe.grid(column = 1, row = 1, padx = 5)        
  
 **In DefineVars add this... **In DefineVars add this...
Ligne 396: Ligne 667:
        # insert([0,ACTIVE,END],item)**        # insert([0,ACTIVE,END],item)**
  
 +Ajoutez ceci dans DefinirVariables :
 +        # les elements pour notre liste 
 +        self.exemples = ['Element un','Element deux','Element trois','Element quatre'       
  
 +Et ajoutez les routines de support suivantes :
 +    def effacerListe(self):
 +        self.liste.delete(0,END)
 +        
 +    def remplirListe(self):
 +        # Note : effacer d'abord la liste ; aucune verification n'est faite
 +        for ex in self.exemples:
 +            self.liste.insert(END,ex)   
 +        # insert([0,ACTIVE,END],element)
  
 **   def LBoxSelect(self,p1): **   def LBoxSelect(self,p1):
Ligne 408: Ligne 691:
 root.geometry('750x370+150+150')** root.geometry('750x370+150+150')**
  
 +    def listeSelection(self,p1):
 +        print("Clic sur un élément de la liste")
 +        items = self.liste.curselection()
 +        selitem = items[0]
 +        print("Index de l'élément choisi : {0}".format(selitem))
 +        print("Texte de l'élément choisi : {0}".format(self.liste.get(selitem)))
  
 +Enfin, mettez à jour la ligne de géométrie :
 +  root.geometry('750x370+150+150')
  
 **Save this as widgetdemo1e.py, and run it. Now we will do our last modifications to our application. **Save this as widgetdemo1e.py, and run it. Now we will do our last modifications to our application.
Ligne 426: Ligne 717:
        self.btnMBYesNo.bind('<ButtonRelease-1>', lambda e: self.ShowMessageBox(5))**        self.btnMBYesNo.bind('<ButtonRelease-1>', lambda e: self.ShowMessageBox(5))**
  
 +Sauvegarder cela comme widgetdemo1e.py et exécutez-le. Maintenant, nous allons faire les dernières modifications à notre application.
  
 +Les boîtes de dialogue
 +
 +Cette section est tout simplement une série de boutons « normaux » qui appellent les différents types de boîtes de dialogue. Nous les avons déjà rencontrés avec une boîte à outils différente. Nous allons explorer seulement 5 types différents, mais il y en a plus. Dans cette section, nous allons regarder Information, Avertissement, Erreur, Question, et Dialogue Oui/Non. Ils sont très utiles lorsque vous avez besoin de faire passer des informations à votre utilisateur d'une manière assez forte. Dans la routine ConstruireWidgets, ajoutez...
 +        # boutons pour afficher les fenetres de messages et de dialogues
 +        self.cadreMessages = Frame(fenetre,relief = SUNKEN,padx = 3, pady = 3, borderwidth = 2)
 +        self.btnMBInfo = Button(self.cadreMessages,text = "Info")
 +        self.btnMBWarning = Button(self.cadreMessages,text = "Avertissement")
 +        self.btnMBError = Button(self.cadreMessages,text = "Erreur")
 +        self.btnMBQuestion = Button(self.cadreMessages,text = "Question")
 +        self.btnMBYesNo = Button(self.cadreMessages,text = "Oui/Non")
 +        self.btnMBInfo.bind('<ButtonRelease-1>', lambda e: self.afficheFenetreMessage(1))
 +        self.btnMBWarning.bind('<ButtonRelease-1>', lambda e: self.afficheFenetreMessage(2))
 +        self.btnMBError.bind('<ButtonRelease-1>', lambda e: self.afficheFenetreMessage(3))
 +        self.btnMBQuestion.bind('<ButtonRelease-1>', lambda e: self.afficheFenetreMessage(4))
 +        self.btnMBYesNo.bind('<ButtonRelease-1>', lambda e: self.afficheFenetreMessage(5))
  
 **Now, add the code for the PlaceWidgets routine: **Now, add the code for the PlaceWidgets routine:
Ligne 438: Ligne 745:
        self.btnMBYesNo.grid(column = 5, row = 0, padx= 3)**        self.btnMBYesNo.grid(column = 5, row = 0, padx= 3)**
  
 +Maintenant ajoutez le code dans la routine PlacerWidgets : 
 +        # boutons de boîtes de messages et cadre 
 +        self.cadreMessages.grid(column = 0,row = 7, columnspan = 5, padx = 5, sticky = 'WE'
 +        l = Label(self.cadreMessages,text='Messages |',width=15, anchor='e').grid(column=0,row=0) 
 +        self.btnMBInfo.grid(column = 1, row = 0, padx= 3) 
 +        self.btnMBWarning.grid(column = 2, row = 0, padx= 3) 
 +        self.btnMBError.grid(column = 3, row = 0, padx= 3) 
 +        self.btnMBQuestion.grid(column = 4, row = 0, padx= 3) 
 +        self.btnMBYesNo.grid(column = 5, row = 0, padx= 3)
  
 **Here is the support routine. For the first three (Info, Warning, and Error), you simply call 'tkMessageBox.showinfo', or whichever you need, with two parameters. First is the title for the message dialog, and second is the actual message you want to show. The icon is handled for you by tkinter. For the dialogs that provide a response (question, yes/no), we provide a variable that receives the value of which button was clicked. In the case of the question dialog, the response is either “yes” or “no”, and, in the case of the yes/no dialog, the response is either “True” or “False”. **Here is the support routine. For the first three (Info, Warning, and Error), you simply call 'tkMessageBox.showinfo', or whichever you need, with two parameters. First is the title for the message dialog, and second is the actual message you want to show. The icon is handled for you by tkinter. For the dialogs that provide a response (question, yes/no), we provide a variable that receives the value of which button was clicked. In the case of the question dialog, the response is either “yes” or “no”, and, in the case of the yes/no dialog, the response is either “True” or “False”.
Ligne 455: Ligne 770:
            print('{0} was pressed...'.format(resp))**            print('{0} was pressed...'.format(resp))**
  
 +Voici la routine d'appui. Pour les trois premiers (Info, Avertissement et Erreur), il suffit d'appeler « tkMessageBox.showinfo », ou celui dont vous avez besoin, avec deux paramètres. Le premier est le titre de la boîte de message et le second est le message réel que vous voulez montrer. L'icône est gérée pour vous par Tkinter. Pour les dialogues qui fournissent une réponse (Question, Oui/Non), nous fournissons une variable qui reçoit la valeur correspondant au bouton cliqué. Dans le cas de la boîte de dialogue Question, la réponse est « Oui » ou « Non », et dans le cas du dialogue Oui/Non, la réponse est « True » ou « False ». 
 +    def afficheFenetreMessage(self,which): 
 +        if which == 1: 
 +            tkMessageBox.showinfo('Demo','Voici un message INFO'
 +        elif which == 2: 
 +            tkMessageBox.showwarning('Demo','Voici un message WARNING (avertissement)'
 +        elif which == 3: 
 +            tkMessageBox.showerror('Demo','Voici un message ERREUR'
 +        elif which == 4: 
 +            rep = tkMessageBox.askquestion('Demo','Voici une QUESTION ?') 
 +            print('clic sur {0}...'.format(rep)) 
 +        elif which == 5: 
 +            rep = tkMessageBox.askyesno('Demo','Voici un message OUI/NON'
 +            print('clic sur {0}...'.format(rep))
  
 **Finally, modify the geometry line: **Finally, modify the geometry line:
Ligne 466: Ligne 794:
 That's it for this time. I hope this has inspired you to explore all of the goodies that tkinter provides. See you next time.** That's it for this time. I hope this has inspired you to explore all of the goodies that tkinter provides. See you next time.**
  
-version française +Enfin, modifiez la ligne de géométrie 
-http://pastebin.com/TQgppVnF+  root.geometry('750x490+550+150'
 + 
 +Sauvegardez ceci sous le nom widgetdemo1f.py et amusez-vous avec. 
 + 
 +J'ai placé le code de widgetdemo1f.py sur pastebin ici : http://pastebin.com/TQgppVnF 
 + 
 +C'est tout pour cette fois. J'espère que ceci vous aura inspiré à explorer toutes les fonctionnalités proposées par tkinter. À la prochaine fois.
  
issue52/tutopython.1315511186.txt.gz · Dernière modification : 2011/09/08 21:46 de fredphil91