Outils pour utilisateurs

Outils du site


issue51:python_partie_25_pp._7-14

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
issue51:python_partie_25_pp._7-14 [2011/08/15 12:16] fredphil91issue51:python_partie_25_pp._7-14 [2011/08/31 21:35] (Version actuelle) fredphil91
Ligne 2: Ligne 2:
 PLEASE NOTE – All of the code presented here is for Python 2.x only. In an upcoming article, we'll discuss how to use tkinter in Python 3.x. If you MUST use Python 3.x, change the import statements to “from tkinter import *”.** PLEASE NOTE – All of the code presented here is for Python 2.x only. In an upcoming article, we'll discuss how to use tkinter in Python 3.x. If you MUST use Python 3.x, change the import statements to “from tkinter import *”.**
  
-Un certain nombre d'entre vous ont commenté les articles de programmation graphique et dit combien vous les avez appréciés. En réponse à cela, nous allons commencer à jeter un oeil à un autre outil d'interfaces graphiques appelé Tkinter. Ceci est la façon "officiellede faire de la programmation graphique en Python. Tkinter existe depuis longtemps et a obtenu un retour assez mauvais pour son côté « démodé ». Ceci a changé récemment, alors j'ai pensé que nous pourrions nous battire contre ce processus de mauvaises pensées+Un certain nombre d'entre vous ont commenté les articles de programmation graphique et dit combien vous les avez appréciés. En réponse à cela, nous allons commencer à jeter un œil à un autre outil d'interfaces graphiques appelé Tkinter. Ceci est la façon « officielle » de faire de la programmation graphique en Python. Tkinter existe depuis longtemps et a une assez mauvaise réputation pour son côté « démodé ». Ceci a changé récemment, alors j'ai pensé que nous pourrions nous battre contre ce mauvais processus de réflexion
-NOTE Tout le code présenté ici est pour Python 2.x seulement. Dans un prochain article, nous allons discuter de la façon d'utiliser Tkinter avec Python 3.x. Si vous DEVEZ utiliser Python 3.x, changer les déclarations d'importation en « from tkinter import * ».+NOTE Tout le code présenté ici est pour Python 2.x seulement. Dans un prochain article, nous allons discuter de la façon d'utiliser Tkinter avec Python 3.x. Si vous DEVEZ utiliser Python 3.x, changez les déclarations d'importation en « from tkinter import * ».
  
 **A Little History And A Bit Of Background **A Little History And A Bit Of Background
Ligne 11: Ligne 11:
 Basically, we have the Toplevel container widget which contains (holds) other widgets. This is the root or master window. Within this root window, we place the widgets we want to use within our program. Each widget, other than the Toplevel root widget container, has a parent. The parent doesn't have to be the root window. It can be a different widget. We'll explore that next month. For this month, everything will have a parent of the root window.** Basically, we have the Toplevel container widget which contains (holds) other widgets. This is the root or master window. Within this root window, we place the widgets we want to use within our program. Each widget, other than the Toplevel root widget container, has a parent. The parent doesn't have to be the root window. It can be a different widget. We'll explore that next month. For this month, everything will have a parent of the root window.**
  
-Un peu d'histoire et un peu de fond.+Un peu d'histoire et un peu de contexte
  
-Tkinter est synonyme de « Tk interface ». Tk est un langage de programmation à lui tout seul, et le module Tkinter nous permet d'utiliser les fonctions de l'interface graphique de ce langage. Il y a un certain nombre de widgets qui viennent nativement avec le module Tkinter. Parmi eux, on trouve des conteneurs de haut niveau (des fenêtres principales), des boutons, des étiquettes, des cadres, des zones de saisie de texte, des cases à cocher, des boutons radio, des canevas, des entrées de texte multilignes, et bien plus encore. Il y a aussi de nombreux modules qui ajoutent des fonctionnalités par dessus Tkinter. Ce mois-ci, nous allons nous concentrer sur quatre widgets. Un conteneur de haut niveau (à partir d'ici je vais essentiellement l'appeler la fenêtre racine), un cadre, des étiquettes et des boutons. Dans le prochain article, nous verrons plus de widgets plus en profondeur.+Tkinter est l'abbréviation de « Tk interface ». Tk est un langage de programmation à lui tout seul, et le module Tkinter nous permet d'utiliser les fonctions de l'interface graphique de ce langage. Il y a un certain nombre de widgets qui viennent nativement avec le module Tkinter. Parmi eux, on trouve des conteneurs de haut niveau (des fenêtres principales), des boutons, des étiquettes, des cadres, des zones de saisie de texte, des cases à cocher, des boutons radio, des canevas, des entrées de texte multilignes, et bien plus encore. Il y a aussi de nombreux modules qui ajoutent des fonctionnalités par dessus Tkinter. Ce mois-ci, nous allons nous concentrer sur quatre widgets. Un conteneur de haut niveau (à partir d'ici je vais essentiellement l'appeler la fenêtre racine), un cadre, des étiquettes et des boutons. Dans le prochain article, nous verrons plus de widgets plus en profondeur.
  
-Fondamentalement, nous avons le widget conteneur de haut niveau qui contient (possède) d'autres widgets. Il s'agit de la fenêtre racine ou principale. Dans cette fenêtre racine, nous plaçons les widgets que nous voulons utiliser dans notre programme. Chaque widget, à l'exception du conteneur racine principal, a un parent. Le parent n'est pas forcément la fenêtre racine ; ça peut être un autre widget. Nous verrons cela le mois prochain. Pour ce mois-ci, tous les widgets auront pour parent la fenêtre racine.+Fondamentalement, nous avons le widget conteneur de haut niveau qui contient d'autres widgets. Il s'agit de la fenêtre racine ou principale. Dans cette fenêtre racine, nous plaçons les widgets que nous voulons utiliser dans notre programme. Chaque widget, à l'exception du conteneur racine principal, a un parent. Le parent n'est pas forcément la fenêtre racine ; ça peut être un autre widget. Nous verrons cela le mois prochain. Pour ce mois-ci, tous les widgets auront pour parent la fenêtre racine.
  
 **In order to place and display the child widgets, we have to use what's called “geometry management”. It's how things get put into the main root window. Most programmers use one of three types of geometry management, either Packer, Grid, or Place management. In my humble opinion, the Packer method is very clumsy. I'll let you dig into that on your own. The Place management method allows for extremely accurate placement of the widgets, but can be complicated. We'll discuss the Place method in a future article set. For this time, we'll concentrate on the Grid method. **In order to place and display the child widgets, we have to use what's called “geometry management”. It's how things get put into the main root window. Most programmers use one of three types of geometry management, either Packer, Grid, or Place management. In my humble opinion, the Packer method is very clumsy. I'll let you dig into that on your own. The Place management method allows for extremely accurate placement of the widgets, but can be complicated. We'll discuss the Place method in a future article set. For this time, we'll concentrate on the Grid method.
Ligne 22: Ligne 22:
 So parent has the grid, the widgets go into the grid positions. At first glance, you might think that this is very limiting. However, widgets can span multiple grid positions in either the column direction, the row direction, or both.** So parent has the grid, the widgets go into the grid positions. At first glance, you might think that this is very limiting. However, widgets can span multiple grid positions in either the column direction, the row direction, or both.**
  
-Afin de placer et d'afficher les widgets enfants, nous devons utiliser ce qu'on appelle la « gestion de géométrie ». C'est la façon dont les choses se placent dans la fenêtre racine principale. La plupart des programmeurs utilisent un des trois types de gestion de géométrie :  Packer, Grid, ou Gestion de la place. À mon humble avis, la méthode Packer est très maladroite. Je vous laisse creuser cela par vous-mêmes. La méthode de gestion de la place permet un placement extrêmement précis des widgets, mais ça peut être compliqué. Nous en reparlerons dans un futur article. Pour cette fois, nous allons nous concentrer sur la méthode de la grille.+Afin de placer et d'afficher les widgets enfants, nous devons utiliser ce qu'on appelle la « gestion de géométrie ». C'est la façon dont les choses se placent dans la fenêtre racine principale. La plupart des programmeurs utilisent un de ces trois types de gestion de géométrie :  Packer, Grid, ou Gestion de la place. À mon humble avis, la méthode Packer est très maladroite. Je vous laisse l'explorer par vous-même. La méthode de gestion de la place permet un placement extrêmement précis des widgets, mais ça peut être compliqué. Nous en reparlerons dans un futur article. Cette fois-ci, nous allons nous concentrer sur la méthode de la grille.
  
-Pensez à un tableur. Il y a des rangées et des colonnes. Les colonnes sont verticales, les lignes sont horizontales. Voici une représentation simple texte des adresses de cellule d'une grille simple de 5 colonnes sur 4 lignes (en haut à droite).+Pensez à un tableur. Il y a des lignes et des colonnes. Les colonnes sont verticales, les lignes sont horizontales. Voici une représentation texte simple des adresses de cellule d'une grille simple de 5 colonnes sur 4 lignes (en haut à droite).
 Le parent possède la grille, les widgets vont dans les positions de la grille. Au premier regard, vous pourriez penser que cela est très limitatif. Toutefois, les widgets peuvent s'étendre sur plusieurs positions sur la grille, soit dans le sens des colonnes, soit dans celui des lignes, ou les deux à la fois. Le parent possède la grille, les widgets vont dans les positions de la grille. Au premier regard, vous pourriez penser que cela est très limitatif. Toutefois, les widgets peuvent s'étendre sur plusieurs positions sur la grille, soit dans le sens des colonnes, soit dans celui des lignes, ou les deux à la fois.
  
Ligne 43: Ligne 43:
 button = Button(root, text = "Hello FullCircle").grid()** button = Button(root, text = "Hello FullCircle").grid()**
  
 +Notre premier exemple
  
 +Notre premier exemple est SUPER simple (seulement quatre lignes), mais explicite.
 +
 +  from Tkinter import *
 +  racine = Tk()
 +  bouton = Button(racine, text = "Bonjour FullCircle").grid()
 +  racine.mainloop()
 +
 +Bon, qu'est-ce qui se passe ici ? La première ligne importe la bibliothèque Tkinter. Ensuite, on instancie l'objet Tk racine (Tk est une partie de Tkinter). Voici la ligne trois.
 +
 +  bouton = Button(racine, text = "Bonjour FullCircle").grid()
  
 **We create a button called button, set its parent to the root window, set its text to “Hello FullCircle,” and set it into the grid. Finally, we call the window's main loop. Very simple from our perspective, but there's a lot that goes on behind the scenes. Thankfully, we don't need to understand what that is at this time. **We create a button called button, set its parent to the root window, set its text to “Hello FullCircle,” and set it into the grid. Finally, we call the window's main loop. Very simple from our perspective, but there's a lot that goes on behind the scenes. Thankfully, we don't need to understand what that is at this time.
Ligne 57: Ligne 68:
 This is the import statement for the Tkinter library.** This is the import statement for the Tkinter library.**
  
 +Nous créons un bouton appelé bouton, définissons son parent à la fenêtre racine, réglons son texte à « Bonjour FullCircle » et le plaçons dans la grille. Enfin, nous appelons la boucle principale de la fenêtre. Ça paraît très simple quand on regarde le code, mais beaucoup de choses se passent dans les coulisses. Heureusement, nous n'avons pas besoin de comprendre tout cela pour l'instant.
 +
 +Exécutez le programme et nous allons voir ce qui se passe. Sur ma machine, la fenêtre principale apparaît en bas à gauche de l'écran. Elle pourrait apparaître ailleurs sur le vôtre. Cliquer sur ​​le bouton ne fait rien. Réparons cela dans notre prochain exemple.
 +
 +Notre deuxième exemple
 +
 +Cette fois, nous allons créer une classe appelée App. Ce sera la classe qui détient effectivement notre fenêtre. Commençons.
 +
 +  from Tkinter import *
  
 +C'est la déclaration d'importation pour la bibliothèque Tkinter.
  
 **We define our class, and, in the __init__ routine, we set up our widgets and place them into the grid. **We define our class, and, in the __init__ routine, we set up our widgets and place them into the grid.
Ligne 71: Ligne 92:
 self.btnHello = Button(frame, text="Hello", command=self.SaySomething)** self.btnHello = Button(frame, text="Hello", command=self.SaySomething)**
  
 +Nous définissons notre classe, et dans la routine <nowiki>__init__</nowiki>, nous mettons en place nos widgets et les plaçons dans la grille.
  
 +La première ligne dans la routine <nowiki>__init__</nowiki> crée un cadre qui sera le parent de tous nos autres widgets. Le parent de ce cadre est la fenêtre racine (widget de plus haut niveau). Ensuite, nous définissons un label et deux boutons. Regardons la ligne de création de l'étiquette.
 +
 +  self.lblTexte = Label(cadre, text = "Ceci est un widget label")
 +
 +Nous créons le widget étiquette et l'appelons self.lblTexte. Il hérite de l'objet widget Label. Nous réglons son parent (le cadre) et définissons le texte à afficher (text = "Ceci est un widget label"). C'est aussi simple que cela. Bien sûr, nous pouvons faire beaucoup mieux, mais pour l'instant c'est tout ce dont nous avons besoin. Ensuite, nous mettons en place les deux boutons que nous allons utiliser :
 +
 +  self.btnQuitter = Button(cadre, text="Quitter", fg="red", command=cadre.quit)
 +  self.btnBonjour = Button(cadre, text="Bonjour", command=self.DitUnTruc)
  
 **We name the widgets, set their parent (frame), and set the text we want them to show. Now btnQuit has an attribute marked fg which we set to “red”. You might have guessed this sets the foreground color or text color to the color red. The last attribute is to set the callback command we want to use when the user clicks the button. In the case of btnQuit, it's frame.quit, which ends the program. This is a built in function, so we don't need to actually create it. In the case of btnHello, it's a routine called self.SaySomething. This we have to create, but we have a bit more to go through first. **We name the widgets, set their parent (frame), and set the text we want them to show. Now btnQuit has an attribute marked fg which we set to “red”. You might have guessed this sets the foreground color or text color to the color red. The last attribute is to set the callback command we want to use when the user clicks the button. In the case of btnQuit, it's frame.quit, which ends the program. This is a built in function, so we don't need to actually create it. In the case of btnHello, it's a routine called self.SaySomething. This we have to create, but we have a bit more to go through first.
Ligne 85: Ligne 115:
 self.btnQuit.grid(column = 1, row = 1)** self.btnQuit.grid(column = 1, row = 1)**
  
 +Nous nommons les widgets, fixons leur parent (cadre) et définissons le texte à afficher. Maintenant btnQuitter a un attribut marqué fg que nous avons réglé à « red ». Vous avez deviné que cela définit la couleur d'avant-plan ou la couleur du texte à la couleur rouge. Le dernier attribut sert à définir la commande que nous voulons utiliser lorsque l'utilisateur clique sur le bouton. Dans le cas de btnQuitter, c'est cadre.quit, qui termine le programme. C'est une fonction intégrée, donc nous n'avons pas besoin de la créer. Dans le cas de btnBonjour, c'est une routine appelée self.DitUnTruc. Nous devons créer celle-ci, mais auparavant nous avons encore quelque chose à faire.
 +
 +Nous devons placer nos widgets dans la grille. Voici les lignes à nouveau :
  
 +  cadre.grid(column = 0, row = 0)
 +  
 +  self.lblTexte.grid(column = 0, row = 0, columnspan = 2)
 +  
 +  self.btnBonjour.grid(column = 0, row = 1)
 +  
 +  self.btnQuitter.grid(column = 1, row = 1)
  
 **First, we assign a grid to the frame. Next, we set the grid attribute of each widget to where we want the widget to go. Notice the columnspan line for the label (self.lblText). This says that we want the label to span across two grid columns. Since we have only two columns, that's the entire width of the application. Now we can create our callback function: **First, we assign a grid to the frame. Next, we set the grid attribute of each widget to where we want the widget to go. Notice the columnspan line for the label (self.lblText). This says that we want the label to span across two grid columns. Since we have only two columns, that's the entire width of the application. Now we can create our callback function:
Ligne 102: Ligne 142:
 root.mainloop()** root.mainloop()**
  
 +Tout d'abord, nous attribuons une grille au cadre. Ensuite, nous réglons l'attribut de grille de chaque widget selon l'endroit où nous voulons placer le widget. Notez la ligne « columnspan » pour l'étiquette (self.lblTexte). Cela indique que nous voulons que l'étiquette s'étende sur deux colonnes de la grille. Puisque nous avons seulement deux colonnes, il s'agit de toute la largeur de l'application. Maintenant nous pouvons créer notre fonction de rappel :
  
 + def DitUnTruc(self):
 +    print "Bonjour lecteur du Magazine FullCircle !!"
 +
 +Cela affiche simplement dans la fenêtre du terminal le message "Bonjour lecteur du Magazine FullCircle !!"
 +Enfin, on instancie la classe Tk - notre classe App - et exécutons la boucle principale.
 +
 +  racine = Tk()
 +  app = App(racine)
 +  racine.mainloop()
  
 **Give it a try. Now things actually do something. But again, the window position is very inconvenient. Let's fix that in our next example.  **Give it a try. Now things actually do something. But again, the window position is very inconvenient. Let's fix that in our next example. 
Ligne 118: Ligne 168:
 root.mainloop()** root.mainloop()**
  
 +Essayez le programme. Maintenant, il fait vraiment quelque chose. Mais là encore, la position de la fenêtre est très gênante. Corrigeons cela dans notre prochain exemple.
  
 +Notre troisième exemple
 +
 +Enregistrez l'exemple précédent sous le nom exemple3.py. Tout est exactement pareil, sauf une seule ligne qui se trouve en bas de la routine principale. Je vais vous montrer ces lignes avec la nouvelle :
 +
 +  racine = Tk()
 +  racine.geometry('150x75+550+150')
 +  app = App(racine)
 +  racine.mainloop()
  
 **What this does is force our initial window to be 150 pixels wide and 75 pixels high. We also want the upper left corner of the window to be placed at X-pixel position 550 (right and left) and the Y-pixel position at 150 (top to botton). How did I come up with these numbers? I started with some reasonable values and tweaked them from there. It's a bit of a pain in the neck to do it this way, but the results are better than not doing it at all. **What this does is force our initial window to be 150 pixels wide and 75 pixels high. We also want the upper left corner of the window to be placed at X-pixel position 550 (right and left) and the Y-pixel position at 150 (top to botton). How did I come up with these numbers? I started with some reasonable values and tweaked them from there. It's a bit of a pain in the neck to do it this way, but the results are better than not doing it at all.
Ligne 130: Ligne 189:
 Outside of the geometry statement, this (left) should be pretty easy for you to understand by now. Remember, pick some reasonable values, tweak them, and then move on.** Outside of the geometry statement, this (left) should be pretty easy for you to understand by now. Remember, pick some reasonable values, tweak them, and then move on.**
  
 +Ceci force notre fenêtre initiale à une taille de 150 pixels de large sur 75 pixels de haut. Nous voulons aussi que le coin supérieur gauche de la fenêtre soit placé à une position horizontale de 550 pixels (depuis la droite) et à une position verticale de 150 pixels (depuis le haut). Comment suis-je arrivé à ces chiffres ? J'ai commencé avec des valeurs raisonnables et les ai peaufiné à partir de là. C'est un peu difficile de faire de cette façon, mais les résultats sont meilleurs que si on ne fait rien du tout.
 +
 +Notre Quatrième exemple - Une calculatrice simple
 +
 +Maintenant, regardons quelque chose d'un peu plus compliqué. Cette fois, nous allons créer une calculatrice simple à 4 boutons, pour les 4 opérations : addition, soustraction, multiplication et division. À droite vous voyez à quoi elle ressemblera, sous forme de texte simple.
 +
 +Nous allons y plonger tout de suite et je vous expliquerai le code (au milieu à droite) au fur et à mesure.
  
 +À part la déclaration de la géométrie, ceci devrait être assez facile pour vous de comprendre maintenant (à gauche). Rappelez-vous, prenez des valeurs raisonnables, modifiez-les, puis continuez.
  
 **We begin our class definition and set up our __init__ function. We set up three variables as follows: **We begin our class definition and set up our __init__ function. We set up three variables as follows:
Ligne 139: Ligne 206:
 Next, we define the CurrentDisplay variable and assign it to the StringVar object. This is a special object that is part of the Tkinter toolkit. Whatever widget you assign this to automatically updates the value within the widget. In this case, we will be using this to hold whatever we want the display label widget to... er... well... display. We have to instantiate it before we can assign it to the widget. Then we use the built in 'set' function. We then define a boolean variable called DecimalNext, and a variable DecimalCount, and then call the DefineWidgets function, which creates all the widgets, and then call the PlaceWidget function, which actually places them in the root window.** Next, we define the CurrentDisplay variable and assign it to the StringVar object. This is a special object that is part of the Tkinter toolkit. Whatever widget you assign this to automatically updates the value within the widget. In this case, we will be using this to hold whatever we want the display label widget to... er... well... display. We have to instantiate it before we can assign it to the widget. Then we use the built in 'set' function. We then define a boolean variable called DecimalNext, and a variable DecimalCount, and then call the DefineWidgets function, which creates all the widgets, and then call the PlaceWidget function, which actually places them in the root window.**
  
 +Nous commençons notre définition de la classe en mettant en place notre fonction <nowiki>__init__</nowiki>. Nous réglons trois variables comme suit :
  
 +• ValeurCourante - Contient la valeur actuelle qui a été entrée dans la calculatrice.
 +
 +• ValeurAncienne - Contient la valeur qui existait avant que l'utilisateur ne clique sur une touche de fonction.
 +
 +• FonctionCourante - C'est tout simplement pour se souvenir quelle fonction est traitée.
 +
 +Ensuite, nous définissons la variable AffichageCourant et l'attribuons à l'objet StringVar. C'est un objet spécial qui fait partie de la trousse Tkinter. Quel que soit le widget auquel vous l'attribuez, cela met automatiquement à jour la valeur dans le widget. Dans ce cas, nous allons l'utiliser pour contenir ce que nous voulons que le widget d'affichage label... euh... eh bien... affiche. Nous devons l'instancier avant de pouvoir l'assigner au widget. Ensuite, nous utilisons la fonction « set » fournie par Tkinter. Nous définissons ensuite une variable booléenne appelée PartieDecimale et une variable CompteDecimales, puis nous appelons la fonction DefinirWidgets qui crée tous les widgets et ensuite nous appelons la fonction PlacerWidgets, qui les place réellement dans la fenêtre racine.
  
 **def DefineWidgets(self,master): **def DefineWidgets(self,master):
Ligne 147: Ligne 222:
 Now, we have already defined a label earlier. However, this time we are adding a number of other attributes. Notice that we aren't using the 'text' attribute. Here, we assign the label to the parent (master), then set the anchor (or, for our purposes, justification) for the text, when it gets written. In this case, we are telling the label to justify all text to the east or on the right side of the widget. There is a justify attribute, but that's for multiple lines of text. The anchor attribute has the following options... N, NE, E, SE, S, SW, W, NW and CENTER. The default is CENTER. You should think compass points for these. Under normal circumstances, the only really usable values are E (right), W (left), and Center.** Now, we have already defined a label earlier. However, this time we are adding a number of other attributes. Notice that we aren't using the 'text' attribute. Here, we assign the label to the parent (master), then set the anchor (or, for our purposes, justification) for the text, when it gets written. In this case, we are telling the label to justify all text to the east or on the right side of the widget. There is a justify attribute, but that's for multiple lines of text. The anchor attribute has the following options... N, NE, E, SE, S, SW, W, NW and CENTER. The default is CENTER. You should think compass points for these. Under normal circumstances, the only really usable values are E (right), W (left), and Center.**
  
 +  def DefinirWidgets(self,principale):
 +    self.lblAffichage = Label(principale,anchor=E,relief = SUNKEN,bg="white",height=2,textvariable=self.AffichageCourant)
  
 +Bon, nous avons déjà défini un label auparavant. Cependant, cette fois, nous ajoutons un certain nombre d'autres attributs. Notez que nous n'utilisons pas l'attribut « text ». Ici, nous assignons l'étiquette au parent (la fenêtre principale), puis nous définissons l'ancre (ou, pour nos fins, la justification) pour le texte lorsqu'il est écrit. Dans ce cas, nous précisons à l'étiquette de justifier tout le texte à l'est, c'est-à-dire sur le côté droit du widget. Il existe un attribut de justification, mais il sert lorsqu'il y a plusieurs lignes de texte. L'attribut d'ancrage a les options suivantes : N, NE, E, SE, S, SW, W, NW et CENTER. La valeur par défaut est de centrer. Vous devriez penser à des points cardinaux. Dans des circonstances normales, les valeurs réellement utilisables sont E (à droite), W (à gauche), et CENTER (pour centrer).
  
 **Next, we set the relief or visual style of the label. The “legal” options here are FLAT, SUNKEN, RAISED, GROOVE, and RIDGE. The default is FLAT if you don't specify anything. Feel free to try the other combinations on your own after we're done. Next, we set the background (bg) to white in order to set it off from the rest of the window a bit. We set the height to 2 (which is two text lines high, not in pixels), and finally assign the variable we just defined a moment ago (self.CurrentDisplay) to the textvariable attribute. Whenever the value of self.CurrentDisplay changes, the label will change its text to match automatically. **Next, we set the relief or visual style of the label. The “legal” options here are FLAT, SUNKEN, RAISED, GROOVE, and RIDGE. The default is FLAT if you don't specify anything. Feel free to try the other combinations on your own after we're done. Next, we set the background (bg) to white in order to set it off from the rest of the window a bit. We set the height to 2 (which is two text lines high, not in pixels), and finally assign the variable we just defined a moment ago (self.CurrentDisplay) to the textvariable attribute. Whenever the value of self.CurrentDisplay changes, the label will change its text to match automatically.
Ligne 155: Ligne 233:
 I've shown only 4 buttons here. That's because, as you can see, the code is almost exactly the same. Again, we've created buttons earlier in this tutor, but let's take a closer look at what we are doing here.** I've shown only 4 buttons here. That's because, as you can see, the code is almost exactly the same. Again, we've created buttons earlier in this tutor, but let's take a closer look at what we are doing here.**
  
 +Ensuite, nous réglons le relief, qui est le style visuel de l'étiquette. Les options autorisées sont FLAT (à plat), SUNKEN (en creux), RAISED (en relief), GROOVE (en strie) et RIDGE (en arête). La valeur par défaut est à plat si vous ne spécifiez rien. N'hésitez pas à essayer les autres combinaisons par vous-mêmes lorsque nous aurons fini. Ensuite, nous définissons le fond (bg) à blanc afin de le démarquer un peu du reste de la fenêtre. Nous fixons la hauteur à 2 (qui signifie deux lignes de texte de haut, et non pas 2 pixels) et enfin nous assignons la variable que nous venons de définir juste avant (self.AffichageCourant) à l'attribut textvariable. À chaque fois que la valeur de self.AffichageCourant changera, le label modifiera son texte pour correspondre automatiquement.
 +
 +Ci-dessus, nous allons créer quelques-uns des boutons.
  
 +J'ai montré seulement 4 boutons ici. C'est parce que, comme vous pouvez le voir, le code est presque exactement le même. Encore une fois, nous avons créé des boutons plus tôt dans ce tutoriel, mais nous allons regarder de plus près ce que nous faisons ici.
  
 **We start by defining the parent (master), the text that we want on the button, and the width and height. Notice that the width is in characters and the height is in text lines. If you were doing a graphic in the button, you would use pixels to define the height and width. This can become a bit confusing until you get your head firmly wrapped around it. Next, we are setting the bind attribute. When we did the buttons in the previous examples, we used the 'command=' attribute to define what function should be called when the user clicks the button. This time, we are using the '.bind' attribute. It's almost the same thing, but this is an easier way to do it, and to pass information to the callback routine that is static. Notice that here we are using '<ButtonRelease-1>' as the trigger for the bind. In this case, we want to make sure that it's only after the user clicks AND releases the left mouse button that we make our callback. Lastly, we define the callback we want to call, and what we are going to pass to it. Now, those of you who are astute (which is each and every one of you) will notice something new. The 'lambda e:' call.  **We start by defining the parent (master), the text that we want on the button, and the width and height. Notice that the width is in characters and the height is in text lines. If you were doing a graphic in the button, you would use pixels to define the height and width. This can become a bit confusing until you get your head firmly wrapped around it. Next, we are setting the bind attribute. When we did the buttons in the previous examples, we used the 'command=' attribute to define what function should be called when the user clicks the button. This time, we are using the '.bind' attribute. It's almost the same thing, but this is an easier way to do it, and to pass information to the callback routine that is static. Notice that here we are using '<ButtonRelease-1>' as the trigger for the bind. In this case, we want to make sure that it's only after the user clicks AND releases the left mouse button that we make our callback. Lastly, we define the callback we want to call, and what we are going to pass to it. Now, those of you who are astute (which is each and every one of you) will notice something new. The 'lambda e:' call. 
Ligne 161: Ligne 243:
 In Python, we use Lambda to define anonymous functions that will appear to interpreter as a valid statement. This allows us to put multiple segments into a single line of code. Think of it as a mini function. In this case, we are setting up the name of the callback function and the value we want to send as well as the event tag (e:). We'll talk more about Lambda in a later article. For now, just follow the example.** In Python, we use Lambda to define anonymous functions that will appear to interpreter as a valid statement. This allows us to put multiple segments into a single line of code. Think of it as a mini function. In this case, we are setting up the name of the callback function and the value we want to send as well as the event tag (e:). We'll talk more about Lambda in a later article. For now, just follow the example.**
  
- +Nous commençons par définir le parent (la fenêtre principale), le texte que nous voulons sur le bouton, et la largeur et la hauteur. Notez que la largeur est en caractères et la hauteur est en lignes de texte. Si vous vouliez un graphique dans le bouton, vous utiliseriez des pixels pour définir la hauteur et la largeur. Cela peut devenir un peu confus jusqu'à ce que vous le compreniez sans faille. Ensuite, nous réglons l'attribut « bind ». Quand nous avons fait des boutons dans les exemples précédents, nous avons utilisé l'attribut « command= » pour définir quelle fonction serait appelée lorsque l'utilisateur clique sur le bouton. Cette fois, nous utilisons l'attribut « .bind » [Ndt : « relier »]. C'est presque la même chose, mais c'est un moyen plus facile de le faire et de transmettre des informations à la routine de rappel qui est statique. Notez que nous utilisons ici « <ButtonRelease-1> » comme l'élément déclencheur de la liaison. Dans ce cas, nous voulons nous assurer que l'appel de la fonction se fait seulement après que l'utilisateur clique ET relâche le bouton gauche de la souris. Enfin, nous définissons la fonction de rappel que nous voulons utiliser et ce que nous allons lui envoyer. Maintenant, ceux d'entre vous qui sont astucieux (ce qui est bien sûr votre cas à tous) noteront quelque chose de nouveau. L'appel « lambda e: ». 
 + 
 +En Python, nous utilisons Lambda pour définir des fonctions anonymes qui apparaîtront à l'interpréteur comme des instructions valides. Cela nous permet de mettre plusieurs morceaux dans une seule ligne de code. Pensez-y comme à une mini-fonction. Dans ce cas, nous mettons en place le nom de la fonction de rappel et la valeur que nous voulons lui envoyer, ainsi que la balise événement (e:). Nous parlerons plus en détail de Lambda dans un article ultérieur. Pour l'instant, il suffit de suivre l'exemple.
  
 **I've given you the first four buttons. Copy and paste the above code for buttons 5 through 9 and button 0. They are all the same with the exception of the button name and the value we send the callback. Next steps are shown right. **I've given you the first four buttons. Copy and paste the above code for buttons 5 through 9 and button 0. They are all the same with the exception of the button name and the value we send the callback. Next steps are shown right.
Ligne 171: Ligne 255:
 Let's say the user wants to enter 563 + 127 and get the answer. They will press or click (logically) 5, then 6, then 3, then the “+,” then 1, then 2, then 7, then the “=” buttons. How do we handle this in code? We have already set the callbacks for the number buttons to the funcNumButton function. There's two ways to handle this. We can keep the information entered as a string and then when we need to convert it into a number, or we can keep it as a number the entire time. We will use the latter method. To do this, we will keep the value that is already there (0 when we start) in a variable called “self.CurrentValue”, When a number comes in, we take the variable, multiply it by 10 and add the new value. So, when the user enters 5, 6 and 3, we do the following...** Let's say the user wants to enter 563 + 127 and get the answer. They will press or click (logically) 5, then 6, then 3, then the “+,” then 1, then 2, then 7, then the “=” buttons. How do we handle this in code? We have already set the callbacks for the number buttons to the funcNumButton function. There's two ways to handle this. We can keep the information entered as a string and then when we need to convert it into a number, or we can keep it as a number the entire time. We will use the latter method. To do this, we will keep the value that is already there (0 when we start) in a variable called “self.CurrentValue”, When a number comes in, we take the variable, multiply it by 10 and add the new value. So, when the user enters 5, 6 and 3, we do the following...**
  
 +Je vous ai donné les quatre premiers boutons. Copiez et collez le code ci-dessus pour les boutons de 5 à 9 et pour le bouton 0. Ils sont tous identiques, à l'exception du nom du bouton et de la valeur que nous envoyons au rappel. Les prochaines étapes sont indiquées à droite.
 +
 +La seule chose dont nous n'avons pas parlé pour l'instant, ce sont les attributs « columnspan » et « sticky ». Comme je l'ai mentionné auparavant, un widget peut s'étendre sur plus d'une colonne ou une ligne. Dans ce cas, nous « étirons » le widget étiquette sur les quatre colonnes. C'est ce que fait l'attribut « columnspan ». Il existe également un attribut « rowspan ». L'attribut « sticky » [Ndt : « collant »] indique au widget où aligner ses bords. Pensez-y comme la manière dont le widget se remplit au sein de la grille. En haut à gauche vous voyez le reste de nos boutons.
 +
 +Avant d'aller plus loin nous allons jeter un œil à la façon dont les choses vont fonctionner quand l'utilisateur appuiera sur les boutons.
  
 +Disons que l'utilisateur veut saisir 563 + 127 et obtenir la réponse. Il appuiera ou cliquera (logiquement) sur 5, puis 6, puis 3, puis le « + », puis 1, puis 2, puis 7, puis le bouton « = ». Comment pouvons-nous gérer cela dans le code ? Nous avons déjà réglé les rappels pour les touches numériques à la fonction foncBoutonNumerique. Il y a deux façons de gérer cela. Nous pouvons conserver les informations saisies comme une chaîne et puis la convertir en nombre quand nous avons besoin, ou bien nous pouvons le garder comme un nombre tout le temps. Nous allons utiliser cette dernière méthode. Pour ce faire, nous allons conserver la valeur qui est déjà là (0 quand nous commencerons) dans une variable appelée "self.ValeurCourante", puis quand un nouveau chiffre arrive, nous prenons la variable, la multiplions par 10 et ajoutons la nouvelle valeur. Ainsi, lorsque l'utilisateur entre 5, 6 et 3, nous faisons les choses suivantes...
  
 **User clicks 5 – 0 * 10 + 5 (5) **User clicks 5 – 0 * 10 + 5 (5)
Ligne 185: Ligne 275:
 Above is the code to start defining our callbacks.** Above is the code to start defining our callbacks.**
  
 +L'utilisateur clique 5 : 0 * 10 + 5 (5)
  
 +L'utilisateur clique 6 : 5 * 10 + 6 (56)
 +
 +L'utilisateur clique 3 : 56 * 10 + 3 (563)
 +
 +Bien sûr, nous devons ensuite afficher la variable « self.ValeurCourante » dans l'étiquette.
 +
 +Ensuite, l'utilisateur clique sur le bouton « + ». Nous prenons la valeur de « self.ValeurCourante » et la plaçons dans la variable « self.ValeurAncienne » et réinitialisons "self.ValeurCourante" à 0. Nous devons ensuite répéter le processus pour les clics sur 1, 2 et 7. Lorsque l'utilisateur clique sur la touche « = », nous devons ensuite ajouter les valeurs de « self.ValeurCourante » et « self.ValeurAncienne », les afficher, puis effacer les deux variables pour continuer.
 +
 +Ci-dessus, voici le code pour commencer à définir nos fonctions de rappel.
  
 **The “funcNumButton routine receives the value we passed from the button press. The only thing that is different from the example above is what if the user pressed the decimal button (“.”). Below, you'll see that we use a boolean variable to hold the fact they pressed the decimal button, and, on the next click, we deal with it. That's what the “if self.DecimalNext == True:” line is all about. Let's walk through it. **The “funcNumButton routine receives the value we passed from the button press. The only thing that is different from the example above is what if the user pressed the decimal button (“.”). Below, you'll see that we use a boolean variable to hold the fact they pressed the decimal button, and, on the next click, we deal with it. That's what the “if self.DecimalNext == True:” line is all about. Let's walk through it.
  
-The user clicks 3, then 2, then the decimal, then 4, to create “32.4”. We handle the 3 and 2 clicks through the “funcNumButton” routine. We check to see if self.DecimalNext is True (which in this case it isn't until the user clicks the “.” button). If not, we simply multiply the held value (self.CurrentValue) by 10 and add the incoming value. When the user clicks the “.”, the callback “funcFuncButton” is called with the “Dec” value. All we do is set the boolean variable “self.DecimalNext” to True. When the user clicks the 4, we will test the “self.DecimalNext” value and, since it's true, we play some magic. First, we increment the self.DecimalCount variable. This tells us how many decimal places we are working with. We then take the incoming value, multiply it by (10<nowiki>**</nowiki>-self.DecimalCount). Using this magic operator, we get a simple “raised to the power of” function. For example 10<nowiki>**</nowiki>2 returns 100. 10<nowiki>**</nowiki>-2 returns 0.01. Eventually, using this routine will result in a rounding issue, but for our simple calculator, it will work for most reasonable decimal numbers. I'll leave it to you to work out a better function. Think of this as your homework for this month.**+The user clicks 3, then 2, then the decimal, then 4, to create “32.4”. We handle the 3 and 2 clicks through the “funcNumButton” routine. We check to see if self.DecimalNext is True (which in this case it isn't until the user clicks the “.” button). If not, we simply multiply the held value (self.CurrentValue) by 10 and add the incoming value. When the user clicks the “.”, the callback “funcFuncButton” is called with the “Dec” value. All we do is set the boolean variable “self.DecimalNext” to True. When the user clicks the 4, we will test the “self.DecimalNext” value and, since it's true, we play some magic. First, we increment the self.DecimalCount variable. This tells us how many decimal places we are working with. We then take the incoming value, multiply it by (10<nowiki>*</nowiki><nowiki>*</nowiki>-self.DecimalCount). Using this magic operator, we get a simple “raised to the power of” function. For example 10<nowiki>*</nowiki><nowiki>*</nowiki>2 returns 100. 10<nowiki>*</nowiki><nowiki>*</nowiki>-2 returns 0.01. Eventually, using this routine will result in a rounding issue, but for our simple calculator, it will work for most reasonable decimal numbers. I'll leave it to you to work out a better function. Think of this as your homework for this month.**
  
 +La routine « foncBoutonNumerique » reçoit la valeur que nous lui passons en appuyant sur un bouton. La seule chose qui diffère de l'exemple ci-dessus est lorsque l'utilisateur appuie sur ​​le bouton de décimale (« . »). Ci-dessous, vous verrez que nous utilisons une variable booléenne pour retenir le fait qu'il a déjà appuyé sur le bouton décimal, et, au prochain clic, on s'en occupe. D'où la ligne « if self.PartieDecimale == True: ». Nous allons procéder pas à pas.
  
 +L'utilisateur clique sur 3, puis 2, puis le point décimal, puis 4 pour créer « 32.4 ». Nous traitons les clics sur 3 et 2 grâce à la routine « foncBoutonNumerique ». Nous vérifions pour voir si self.PartieDecimale est vrai (ce qu'il n'est pas tant que l'utilisateur n'a pas cliqué sur le bouton « . »). Sinon, nous multiplions simplement la valeur de self.ValeurCourante par 10 et ajoutons la nouvelle valeur. Lorsque l'utilisateur clique sur le « . », la fonction de rappel « foncBoutonFonction » est appelée avec la valeur « Dec ». Tout ce que nous faisons est de régler la variable booléenne « self.PartieDecimale » à vrai (True). Lorsque l'utilisateur clique sur le 4, nous allons tester la valeur de « self.PartieDecimale » et, puisqu'elle est vraie, nous faisons un peu de magie. Premièrement, on incrémente la variable self.CompteDecimales, qui nous indique le nombre de décimales avec lequel nous travaillons. Nous prenons ensuite la nouvelle valeur entrante, la multiplions par (10<nowiki>*</nowiki><nowiki>*</nowiki>-self.CompteDecimales). En utilisant cet opérateur magique, nous obtenons une simple fonction « élévation à la puissance ». Par exemple 10<nowiki>*</nowiki><nowiki>*</nowiki>2 renvoie 100. 10<nowiki>*</nowiki><nowiki>*</nowiki>-2 retourne 0.01. Parfois, en utilisant cette routine, cela conduit à un problème d'arrondi, mais pour notre calculatrice simple, cela fonctionnera pour la plupart des nombres décimaux raisonnables. Je vais vous laisser le soin de travailler à une meilleure fonction. Prenez cela comme vos devoirs pour ce mois-ci.
  
 **The “funcClear” routine simply clears the two holding variables, then sets the display. **The “funcClear” routine simply clears the two holding variables, then sets the display.
Ligne 205: Ligne 307:
 Now the functions. We've already discussed what happens with the function 'Dec'. We set this one up first with the “if” statement. We go to the “else,” and if the function is anything else, we clear the “self.DecimalNext” and “self.DecimalCount” variables.** Now the functions. We've already discussed what happens with the function 'Dec'. We set this one up first with the “if” statement. We go to the “else,” and if the function is anything else, we clear the “self.DecimalNext” and “self.DecimalCount” variables.**
  
 +La routine « foncEffacer » efface simplement les deux variables mémoire, puis rafraîchit l'affichage.
 +
 +  def foncEffacer(self):
 +    self.ValeurCourante = 0
 +    self.ValeurAncienne = 0
 +    self.Rafraichir()
  
 +Maintenant les fonctions. Nous avons déjà discuté de ce qui se passe avec la fonction « Dec ». Nous l'avons traitée en premier avec l'instruction « if ». Nous allons passer au « else » et, dans le cas où la fonction est autre, nous effaçons les variables « self.PartieDecimale » et « self.CompteDecimales ».
  
 **The next set of steps are shown on the previous page (right hand box). **The next set of steps are shown on the previous page (right hand box).
Ligne 219: Ligne 328:
 Finally we have our startup lines.** Finally we have our startup lines.**
  
 +Les prochaines étapes sont indiquées sur la page précédente (encadré de droite).
  
 +La routine « Rafraichir » règle simplement la valeur de l'étiquette d'affichage. N'oubliez pas que nous avons dit à l'étiquette de « surveiller » la variable « self.AffichageCourant ». À chaque fois que cette variable change, l'étiquette change automatiquement d'affichage pour correspondre. Nous utilisons la  méthode « .set » pour changer la valeur.
 +
 +  def Rafraichir(self):
 +    print('ValeurCourante = {0} - ValeurAncienne = {1}'.format(self.ValeurCourante,self.ValeurAncienne))
 +    self.AffichageCourant.set(self.ValeurCourante)
 +
 +Enfin, nous avons nos lignes de démarrage.
  
 **if __name__ == '__main__': **if __name__ == '__main__':
Ligne 231: Ligne 348:
 Next month, we will continue looking at Tkinter and its wealth of widgets. In a future article, we'll look at a GUI designer for tkinter called PAGE. In the meantime, have fun playing. I think you'll enjoy Tkinter.** Next month, we will continue looking at Tkinter and its wealth of widgets. In a future article, we'll look at a GUI designer for tkinter called PAGE. In the meantime, have fun playing. I think you'll enjoy Tkinter.**
  
 +  if __name__ == '__main__':
 +    Demarrage()
 +
 +Maintenant, vous pouvez exécuter le programme et l'essayer.
 +
 +Comme toujours, le code de cet article peut être trouvé sur PasteBin. Les exemples 1, 2 et 3 sont ici : http://pastebin.com/RAF4KK6E et l'exemple Calc.py est ici : http://pastebin.com/Pxr0H8FJ
 +
 +Le mois prochain, nous allons continuer à explorer Tkinter et la richesse de ses widgets. Dans un prochain article, nous verrons un concepteur d'interface graphique pour Tkinter appelé PAGE. En attendant, amusez-vous bien. Je pense que vous apprécierez Tkinter.
 +
 +====== CODE PAGE 7 ======
 +remplacer l'anglais par COLONNES et LIGNES
 +
 +====== CODE PAGE 8 ======
 +  class App:
 +    def __init__(self, principale):
 +        cadre = Frame(principale)
 +        self.lblTexte = Label(cadre, text = "Voici un widget label")
 +        self.btnQuitter = Button(cadre, text="Quitter", fg="red", command=cadre.quit)
 +        self.btnBonjour = Button(cadre, text="Bonjour", command=self.DitUnTruc)
 +        cadre.grid(column = 0, row = 0)
 +        self.lblTexte.grid(column = 0, row = 0, columnspan = 2)
 +        self.btnBonjour.grid(column = 0, row = 1)
 +        self.btnQuitter.grid(column = 1, row = 1)
 +
 +
 +====== CODE PAGE 9 ======
 +en haut à droite : remplacer CLEAR par EFFACER
 +
 +juste en dessous :
 +
 +  from Tkinter import *
 +  def Demarrage():
 +    global val, calc, racine
 +    racine = Tk()
 +    racine.title('Calculatrice simple')
 +    racine.geometry('247x330+469+199')
 +    calc = Calculatrice(racine)
 +    racine.mainloop()
 +
 +en bas à gauche :
 +
 +  class Calculatrice():
 +    def __init__(self,racine):
 +        principale = Frame(racine)
 +        self.ValeurCourante = 0 
 +        self.ValeurAncienne = 0
 +        self.FonctionCourante = ''
 +        self.AffichageCourant = StringVar()
 +        self.AffichageCourant.set('0')
 +        self.PartieDecimale = False
 +        self.CompteDecimales = 0
 +        self.DefinirWidgets(principale)
 +        self.PlacerWidgets(principale)
 +
 +====== CODE PAGE 10 ======
 +        self.btn1 = Button(principale, text = '1',width = 4,height=3)
 +        self.btn1.bind('<ButtonRelease-1>', lambda e: self.foncBoutonNumerique(1))
 +        self.btn2 = Button(principale, text = '2',width = 4,height=3)
 +        self.btn2.bind('<ButtonRelease-1>', lambda e: self.foncBoutonNumerique(2))
 +        self.btn3 = Button(principale, text = '3',width = 4,height=3)
 +        self.btn3.bind('<ButtonRelease-1>', lambda e: self.foncBoutonNumerique(3))
 +        self.btn4 = Button(principale, text = '4',width = 4,height=3)
 +        self.btn4.bind('<ButtonRelease-1>', lambda e: self.foncBoutonNumerique(4))
 +
 +====== CODE PAGE 11 ======
 +        self.btnDash = Button(principale, text = '-',width = 4,height=3)
 +        self.btnDash.bind('<ButtonRelease-1>', lambda e: self.foncBoutonFonction('SIGNE'))
 +        self.btnDot = Button(principale, text = '.',width = 4,height=3)
 +        self.btnDot.bind('<ButtonRelease-1>', lambda e: self.foncBoutonFonction('Dec'))
 +
 +Le bouton « btnDash » change le signe de la valeur affichée. 523 devient -523 et -523 devient 523. Le bouton btnDot saisit un point décimal. Ces exemples, ainsi que les suivants, utilisent la fonction foncBoutonFonction.
 +
 +        self.btnPlus = Button(principale,text = '+', width = 4, height=3)
 +        self.btnPlus.bind('<ButtonRelease-1>', lambda e: self.foncBoutonFonction('Ajouter'))
 +        self.btnMinus = Button(principale,text = '-', width = 4, height=3)
 +        self.btnMinus.bind('<ButtonRelease-1>', lambda e: self.foncBoutonFonction('Soustraire'))        
 +        self.btnStar = Button(principale,text = '*', width = 4, height=3)
 +        self.btnStar.bind('<ButtonRelease-1>', lambda e: self.foncBoutonFonction('Multiplier'))        
 +        self.btnDiv = Button(principale,text = '/', width = 4, height=3)
 +        self.btnDiv.bind('<ButtonRelease-1>', lambda e: self.foncBoutonFonction('Diviser'))        
 +        self.btnEqual = Button(principale, text = '=')
 +        self.btnEqual.bind('<ButtonRelease-1>', lambda e: self.foncBoutonFonction('Egal'))
 +
 +Voici les quatre boutons pour les fonctions mathématiques.
 +
 +        self.btnClear = Button(principale, text = 'EFFACER')
 +        self.btnClear.bind('<ButtonRelease-1>', lambda e: self.foncEffacer())
 +
 +Enfin, voici le bouton Effacer. Il efface bien sûr les variables et l'affichage. Maintenant nous plaçons les widgets avec la routine PlacerWidgets. D'abord nous initialisons la grille, puis nous plaçons les widgets dedans. Voici la première partie de la routine.
 +
 +    def PlacerWidgets(self,principale):
 +        principale.grid(column=0,row=0)
 +        self.lblAffichage.grid(column=0,row=0,columnspan = 4,sticky=EW)
 +        self.btn1.grid(column = 0, row = 1)
 +        self.btn2.grid(column = 1, row = 1)
 +        self.btn3.grid(column = 2, row = 1)
 +        self.btn4.grid(column = 0, row = 2)
 +        self.btn5.grid(column = 1, row = 2)
 +        self.btn6.grid(column = 2, row = 2)
 +        self.btn7.grid(column = 0, row = 3)
 +        self.btn8.grid(column = 1, row = 3)
 +        self.btn9.grid(column = 2, row = 3)
 +        self.btn0.grid(column = 1, row = 4)
 +
 +====== CODE PAGE 12 ======
 +        self.btnDash.grid(column = 0, row = 4)
 +        self.btnDot.grid(column = 2, row = 4)
 +        self.btnPlus.grid(column = 3,row = 1)
 +        self.btnMinus.grid(column = 3, row = 2)
 +        self.btnStar.grid(column = 3, row = 3)
 +        self.btnDiv.grid(column=3, row = 4)
 +        self.btnEqual.grid(column=0,row=5,columnspan = 4,sticky=NSEW)
 +        self.btnClear.grid(column=0,row=6,columnspan = 4, sticky = NSEW)
 +
 +et en dessous :
 +
 +    def foncBoutonNumerique(self,val):
 +        if self.PartieDecimale == True:
 +            self.CompteDecimales += 1
 +            self.ValeurCourante = self.ValeurCourante + (val * (10**-self.CompteDecimales))
 +        else:
 +            self.ValeurCourante = (self.ValeurCourante * 10) + val        
 +        self.Rafraichir()f.Rafraichir()
 +
 +====== CODE PAGE 13 ======
 +    def foncBoutonFonction(self,fonction):
 +        if fonction == 'Dec':
 +            self.PartieDecimale = True
 +        else:
 +            self.PartieDecimale = False
 +            self.CompteDecimales = 0
 +            if fonction == 'SIGNE':
 +                self.ValeurCourante *= -1
 +                self.Rafraichir()
 +
 +la fonction SIGNE multiplie simplement la valeur courante par -1.
 +
 +            elif fonction == 'Ajouter':
 +                self.ValeurAncienne = self.ValeurCourante
 +                self.ValeurCourante = 0
 +                self.FonctionCourante = 'Ajouter'
 +
 +La fonction Ajouter recopie « self.ValeurCourante » dans « self.ValeurAncienne », efface « self.ValeurCourante », et règle « self.FonctionCourante » à « Ajouter ». Les fonctions Soustraire, Multiplier et Diviser font la même chose avec les mots-clés appropriés.
 +
 +            elif fonction == 'Soustraire':
 +                self.ValeurAncienne = self.ValeurCourante
 +                self.ValeurCourante = 0
 +                self.FonctionCourante = 'Soustraire'
 +            elif fonction == 'Multiplier':
 +                self.ValeurAncienne = self.ValeurCourante
 +                self.ValeurCourante = 0
 +                self.FonctionCourante = 'Multiplier'
 +            elif fonction == 'Diviser':
 +                self.ValeurAncienne = self.ValeurCourante
 +                self.ValeurCourante = 0
 +                self.FonctionCourante = 'Diviser'            
 +
 +La fonction Egal est l'endroit où se produit la « magie ». Vous comprendrez facilement le code ci-dessous maintenant.
 +
 +            elif fonction == 'Egal':
 +                if self.FonctionCourante == 'Ajouter':
 +                    self.ValeurCourante += self.ValeurAncienne
 +                elif self.FonctionCourante == 'Soustraire':
 +                    self.ValeurCourante = self.ValeurAncienne - self.ValeurCourante
 +                elif self.FonctionCourante == 'Multiplier':
 +                    self.ValeurCourante *= self.ValeurAncienne
 +                elif self.FonctionCourante == 'Diviser':
 +                    self.ValeurCourante = self.ValeurAncienne / self.ValeurCourante
 +                self.Rafraichir()
 +                self.ValeurCourante = 0
 +                self.ValeurAncienne = 0
  
issue51/python_partie_25_pp._7-14.1313403366.txt.gz · Dernière modification : 2011/08/15 12:16 de fredphil91