Outils pour utilisateurs

Outils du site


issue155:python

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
issue155:python [2020/04/03 08:58] d52frissue155:python [2020/04/04 18:00] (Version actuelle) andre_domenech
Ligne 3: Ligne 3:
 As most of you know, I act as an unofficial support outlet for Page, the GUI designer for Python using Tkinter. On average, I spend probably 5 hours a week answering questions from users, both brand new to Page and users who have been using Page for years. I also help out Don Rozenberg with testing new development builds, trying to break it in as many ways as I can. Once I can’t break it anymore, Don usually creates a release. It’s a very time consuming job, but one I really enjoy.** As most of you know, I act as an unofficial support outlet for Page, the GUI designer for Python using Tkinter. On average, I spend probably 5 hours a week answering questions from users, both brand new to Page and users who have been using Page for years. I also help out Don Rozenberg with testing new development builds, trying to break it in as many ways as I can. Once I can’t break it anymore, Don usually creates a release. It’s a very time consuming job, but one I really enjoy.**
  
-Une rapide mise à jour à propos de la bibliothèque recipe-scrapers dont j'ai parlé le mois dernier. Actuellement, il y a 47 sites différents de recettes qui sont supportés, dont les 5 dont j'ai parlé pour le projet. Quelques autres sites marchent sur le projet, ce qui fait continuellement monter leur nombre. beaucoup des extracteurs sont dédiés à des sites hors des USA dans de nombreuses langues différentes. J'expliquerai probablement le processus de création de votre propre extracteur dans un article futur.+Une rapide mise à jour à propos de la bibliothèque recipe-scrapers dont j'ai parlé le mois dernier. Actuellement, 47 sites différents de recettes sont supportés, comprenant les 5 dont j'ai parlé pour le projet. Je travaille sur quelques autres sites pour le projet, ce qui fait continuellement monter leur nombre. Beaucoup des extracteurs sont dédiés à des sites hors des USA dans de nombreuses langues différentes. J'expliquerai probablement le processus de la création de votre propre extracteur dans un article futur.
  
-Comme la plupart d'entre vous le savent, je suis un emplacement de support officieux de Page, le concepteur en affichage graphique pour Python utilisant Tkinter. En moyenne, je passe 5 heures par semaine à répondre aux questions des utilisateurs, que ce soit de tous nouveaux utilisateurs ou des utilisateurs qui utilisent Page depuis des années. J'aide aussi Don Rozenberg en testant les compilations du développement, en essayant de les casser par des moyens aussi différents que possible. Une fois que je n'arrive plus à le détruire, Don crée généralement une version publiée. C'est un travail qui demande beaucoup de temps, mais que j'adore.+Comme la plupart d'entre vous le savent, je suis un point de contact de support officieux de Page, le concepteur en affichage graphique pour Python utilisant Tkinter. En moyenne, je passe 5 heures par semaine à répondre aux questions des utilisateurs, que ce soit de tout nouveaux utilisateurs ou des utilisateurs qui utilisent Page depuis des années. J'aide aussi Don Rozenberg en testant les compilations du développement, en essayant de les casser par des moyens aussi différents que possible. Lorsque je n'arrive plus à les détruire, Don crée généralement une version publiée. C'est un travail qui demande beaucoup de temps, mais que j'adore.
  
 **Of all the questions I get about using Page, the one I get the most is how to create a program with multiple forms. The answer to this is really pretty easy, but is not as straight-forward as a user would think, hence the questions. The next question is how do I get the forms or windows to communicate with each other. My good friend Halvard from Norway asked how to have one form read information from another in “real time”. Again, while the answer is easy, it’s not something that most users would try before they ask the question. So, in this edition, I intend to present a very simple demo to help understand the process. AND there’s an added benefit in that this solution is not limited to a Page GUI program. It can be used for any Python program including CLI programs. Your imagination is the only limit. **Of all the questions I get about using Page, the one I get the most is how to create a program with multiple forms. The answer to this is really pretty easy, but is not as straight-forward as a user would think, hence the questions. The next question is how do I get the forms or windows to communicate with each other. My good friend Halvard from Norway asked how to have one form read information from another in “real time”. Again, while the answer is easy, it’s not something that most users would try before they ask the question. So, in this edition, I intend to present a very simple demo to help understand the process. AND there’s an added benefit in that this solution is not limited to a Page GUI program. It can be used for any Python program including CLI programs. Your imagination is the only limit.
Ligne 13: Ligne 13:
 The project will consist of two Page forms, one called “Parent” and the other called “Child”. The Parent program will launch the Child program and will receive data from the child.** The project will consist of two Page forms, one called “Parent” and the other called “Child”. The Parent program will launch the Child program and will receive data from the child.**
  
-Parmi toutes les questions que je reçois sur l'utilisation de Page, la plus courante est comment créer un programme avec plusieurs formulaires. La réponse à cela est vraiment très simple, mais elle n'est pas aussi directe que ce que pourrait penser l'utilisateur, d'où les questions. La question suivante est comment je trouve les formulaires ou les fenêtres pour communiquer entre eux. Mon cher ami Halvard de Norvège m'a demandé comment faire pour qu'un formulaire lise une information dans un autre en « temps réel ». À nouveau, alors que la réponse est simple, ce n'est pas quelque chose que les utilisateurs essaient avant de poser leur question. Aussi, dans ce numéro, j'ai l'intention de présenter un démo simple pour aider à comprendre le processus. ET, s'ajoute un bénéfice : cette solution n'est pas limitée au programme d'affichage graphique Page. Elle peut être utilisée pour n'importe quel programme en Python, même avec ceux en ligne de commande. Votre imagination est la seule limitation.+Parmi toutes les questions que je reçois sur l'utilisation de Page, la plus courante est comment créer un programme avec plusieurs formulaires. La réponse à cela est vraiment très simple, mais elle n'est pas aussi directe que ce que pourrait penser l'utilisateur, d'où les questions. La question suivante est comment je fais en sorte que les formulaires ou les fenêtres communiquent entre eux. Mon cher ami Halvard de Norvège m'a demandé comment faire pour qu'un formulaire lise une information dans un autre formulaire en « temps réel ». À nouveau, alors que la réponse est simple, ce n'est pas quelque chose que les utilisateurs essaient avant de poser leur question. Aussi, dans ce numéro, j'ai l'intention de présenter une démo simple pour aider à comprendre le processus. ET, s'ajoute un bénéfice : cette solution n'est pas limitée au programme d'affichage graphique Page. Elle peut être utilisée pour n'importe quel programme en Python, même avec ceux en ligne de commande. Votre imagination est la seule limitation.
  
-Aussi, j'ai pensé mettre sur pied une rapide démo en utilisant Page pour montrer comment accorder ces deux idées. Je vais utiliser Page car le programme est beaucoup plus facile à montrer en affichage graphique et parce que la première question a trait aux programmes Pages avec plusieurs formulaires.+Aussi, j'ai pensé mettre sur pied une rapide démo en utilisant Page pour montrer comment gérer les deux idées. Je vais utiliser Page car le programme est beaucoup plus facile à montrer en affichage graphique et parce que la première question a trait aux programmes Pages avec plusieurs formulaires.
  
-Le projet sera constitué de deux formulaires Pages, l'un appelé « Parent », l'autre « Child » (Enfant). Le programme Parent lancera le programme Enfant et recevra des données de cet enfant.+Le projet sera constitué de deux formulaires Page, l'un appelé « Parent », l'autre« Child » (Enfant). Le programme Parent lancera le programme Enfant et recevra des données de cet enfant.
  
 **Form Design **Form Design
Ligne 25: Ligne 25:
 Below is what the Parent form looks like. I didn’t spend much time on making it pretty and mainly kept the attributes for everything on the form to their defaults where possible.** Below is what the Parent form looks like. I didn’t spend much time on making it pretty and mainly kept the attributes for everything on the form to their defaults where possible.**
  
-Conception de formulaire+Conception des formulaires
  
-Nous créerons d'abord le formulaire Parent. Je ne vous ennuierai pas avec les détails de la création du formulaire. Je vous fournirai simplement une copie d'écran de celui-ci et vous donnerai une petite quantité d'informations importantes sur des attributs spéciaux de certains gadgets.+Nous créerons d'abord le formulaire Parent. Je ne vous ennuierai pas avec les détails de la création du formulaire. Je vous fournirai simplement une copie d'écran de celui-ci et vous donnerai une pincée d'informations importantes sur des attributs spéciaux de certains gadgets.
  
 Ci-dessous, voici à quoi ressemble le formulaire Parent. Je n'ai pas passé beaucoup de temps à l'arranger et j'ai principalement gardé les attributs à leur valeur par défaut partout où c'était possible. Ci-dessous, voici à quoi ressemble le formulaire Parent. Je n'ai pas passé beaucoup de temps à l'arranger et j'ai principalement gardé les attributs à leur valeur par défaut partout où c'était possible.
Ligne 35: Ligne 35:
 btnLaunch has the command attribute set to “on_btnLaunch” and the btnExit has the command attribute set to “on_btnExit”. These are the names of the callback functions for each of the buttons. The only other in the top_level form is the title of “I am Parent”.** btnLaunch has the command attribute set to “on_btnLaunch” and the btnExit has the command attribute set to “on_btnExit”. These are the names of the callback functions for each of the buttons. The only other in the top_level form is the title of “I am Parent”.**
  
-Comme vous pouvez le voir, le formulaire est très simple. Deux boutons et quatre étiquettes. Les deux boutons ont pour nom ou alias (de gauche à droite) btnLaunch et btnExit. Puis deux étiquettes statiques (status et received) et deux étiquettes dynamiquesl'un qui est un simple carré coloré qui montre l'état de la connexion au formulaire enfant et l'autre qui se présente sous la forme d'un champ nervuré raffiné) qui a une variable de type texte appelée DataReceived, pour ainsi être facilement mis à jour par programmation. Comme le suggère son nom de variable, il contiendra les données qui arriveront du formulaire enfant. Avant de sauvegarder le formulaire, je l'ai déplacé vers la gauche au milieu de l'écran. La forme enfant se positionnera à droite au milieu de l'écran.+Comme vous pouvez le voir, le formulaire est très simple. Deux boutons et quatre étiquettes. Les deux boutons ont pour nom ou alias (de gauche à droite) btnLaunch et btnExit. Puis il y a deux étiquettes statiques (status et received) et deux étiquettes dynamiques l'une est un simple carré coloré qui montre l'état de la connexion au formulaire enfant et l'autre (qui se présente sous la forme d'un champ nervuré raffiné) a une variable de type texte appelée DataReceived, pour être ainsi facilement mise à jour par programmation. Comme le suggère son nom de variable, elle contiendra les données qui arriveront du formulaire enfant. Avant de sauvegarder le formulaire, je l'ai déplacé vers la gauche au milieu de l'écran. La forme enfant se positionnera à droite au milieu de l'écran.
  
-btnLaunch a l'attribut de commande positionné sur « on_btnLaunch » et btnExit a son attribut de commande paramétré sur « on_btnExit ». Ce sont les noms de fonctions de rappel de chacun des boutons. La seule autre chose est, en haut du formulairele titre « I am Parent » (Je suis le Parent).+btnLaunch a l'attribut de commande positionné sur « on_btnLaunch » et l'attribut de commande de btnExit est paramétré sur « on_btnExit ». Ce sont les noms de fonctions de rappel de chacun des boutons. La seule autre chose dans le formulaire top_level (de niveau haut) est le titre « I am Parent » (Je suis le Parent).
  
 **Next, we’ll design our child program. This one is a bit more complicated, but not horribly so. **Next, we’ll design our child program. This one is a bit more complicated, but not horribly so.
Ligne 49: Ligne 49:
 Ensuite, nous construirons notre programme enfant. Il est un peu plus compliqué, mais pas trop quand même. Ensuite, nous construirons notre programme enfant. Il est un peu plus compliqué, mais pas trop quand même.
  
-Comme vous pouvez le voir, il y a un petit pavé numérique du genre « 10 touches » avec trois boutons annexes, le tout dans un cadre. Il y a aussi une étiquette qui affichera la valeur de la touche appuyée , dont la variable texte est paramétrée sur DisplayLabel. Les boutons annexes sont Clear (Effacer), Bksp (Backspace, retour arrière) et Enter (Entrée). Pour le moment, le bouton Enter ne sert à rien. Il y a aussi un bouton Exit (Sortie).+Comme vous pouvez le voir, il y a un petit pavé numérique du genre « 10 touches » avec trois boutons annexes, le tout dans un cadre. Il y a aussi une étiquette qui affichera la valeur de la touche enfoncée, dont la variable texte est paramétrée sur DisplayLabel. Les boutons annexes sont Clear (Effacer), Bksp (Backspace, retour arrière) et Enter (Entrée). Pour le moment, le bouton Enter ne sert à rien. Il y a aussi un bouton Exit (Sortie).
  
-Les trois boutons complémentaires ont leurs attributs de commande paramétérés sur on_btnClear, on_btnBackspace et on_btnEnter, qui sont, là encore, des fonctions de rappel, et le bouton Exit a son attribut de commande paramétré sur on_btnExit.+Les trois boutons complémentaires ont leurs attributs de commande paramétrés sur on_btnClear, on_btnBackspace et on_btnEnter, qui sont, là encore, des fonctions de rappel, et le bouton Exit a son attribut de commande paramétré sur on_btnExit.
  
-Les 11 boutons du pavé n'utilisent pas d'attributs de commande paramétrés, car il plus facile de paramétrer des fonctions de rappel, qui nécessitent un paramètre contenant quel bouton a été cliqué, en utilisant la commande bind ce que nous verrons dans quelques minutes. Nous paramétrerons les liaisons dans le module _support.+Les 11 boutons du pavé n'utilisent pas d'attributs de commande paramétrés, car il est plus facile de paramétrer des fonctions de rappel, qui nécessitent un paramètre contenant le bouton sur lequel on a cliqué, en utilisant la commande bindce que nous verrons dans quelques minutes. Nous paramétrerons les liaisons dans le module _support.
  
 **The Communications Magic **The Communications Magic
Ligne 71: Ligne 71:
 Import partagé Import partagé
  
-Le fichier lui-même est en fait un fichier vide. Il n'y a rien dedans. Cependant, comme il est importé par nos deux programmes, il peuvent le lire et y écrire.+Le fichier lui-même est en fait un fichier vide. Il n'y a rien dedans. Cependant, comme il est importé par nos deux programmes, ils peuvent le lire et y écrire.
  
 Malgré tout, vous devez rester prudent pour vous assurer que, avant d'essayer de lire la valeur d'une variable à l'intérieur, la valeur a déjà été écrite dans le module partagé. Nous en parlerons un peu plus quand nous examinerons le code. Malgré tout, vous devez rester prudent pour vous assurer que, avant d'essayer de lire la valeur d'une variable à l'intérieur, la valeur a déjà été écrite dans le module partagé. Nous en parlerons un peu plus quand nous examinerons le code.
Ligne 90: Ligne 90:
 Le Code Le Code
  
-Le code des deux modules _support.py sera présenté ci-dessous. Il est montré quasiment complet. Le code des fichiers d'affichage graphique n'est pas montré, ni celui des fichiers .tcl ; cependant, les fichiers GUI;py seront disponibles dans le dépôt pastebin de sorte que vous pourrez vraiment lanvcer les programmes.+Le code des deux modules _support.py sera présenté ci-dessous. Il est montré quasiment complet. Le code des fichiers d'affichage graphique n'est pas montré, ni celui des fichiers .tcl ; cependant, les fichiers GUI.py seront disponibles dans le dépôt pastebin de sorte que vous pourrez vraiment lancer les programmes.
  
 Comme toujours, nous commencerons par la section des imports pour le fichier parent_support.py. Notez que nous importons child.py, child_support.py et shared.py : Comme toujours, nous commencerons par la section des imports pour le fichier parent_support.py. Notez que nous importons child.py, child_support.py et shared.py :
Ligne 99: Ligne 99:
 import shared import shared
  
-La fonction suivante (ci-dessous) est nous fournie par Page ; c'est la fonction set_Tk_var. Elle nous donne accès à l'étiquette qui affiche les vlaeurs générées par le programme enfant.+La fonction suivante (ci-dessous) nous est fournie par Page ; c'est la fonction set_Tk_var. Elle nous donne accès à l'étiquette qui affiche les valeurs générées par le programme enfant.
  
  
Ligne 106: Ligne 106:
 The first two lines of my added code, set two variables in the shared module. That way, when the child program starts up, the variables are already there and can be written to when needed. We also use those variables in the next function so they need to be initialized right away. If we don’t, Python will throw an error.** The first two lines of my added code, set two variables in the shared module. That way, when the child program starts up, the variables are already there and can be written to when needed. We also use those variables in the next function so they need to be initialized right away. If we don’t, Python will throw an error.**
  
-Ensuite (page suivante, en bas à gauche), voici la fonction init. C'est la toute dernière chose qui est lancée dans le programme avant que l'affichage graphique soir révélé à l'utilisateur ; aussi, nous lançons toutes les tâches d'initialisation et de paramétrage à partir de cette fonction. La partie haute a déjà été écrite par Page pour nous. Je fournis toujours le champ de commentaire, juste pour me donner un « repère » pour trouver facilement la fonction.  Nous parlerons ci-dessous du code que j'ai ajouté...+Ensuite (page suivante, en bas à gauche), voici la fonction init. C'est la toute dernière chose qui est lancée dans le programme avant que l'affichage graphique ne soit révélé à l'utilisateur ; aussi, nous lançons toutes les tâches d'initialisation et de paramétrage à partir de cette fonction. La partie haute a déjà été écrite par Page pour nous. Je fournis toujours le champ de commentaire, juste pour me donner un « repère » pour trouver la fonction facilement. Nous parlerons ci-dessous du code que j'ai ajouté...
  
-Les deux premières lignes du code que j'ai ajouté paramètrent deux variables dans le module partagé. De cette façon, quand le programme enfant démarre, les variables sont déjà présnetes et peuvent être écrites quand on en a besoin. Nous utilisons aussi ces variables dans la fonction suivante ; c'est pourquoi nous devons les paramétrer tout de suite. Si nous ne le faisons pas, Python sortira une erreur.+Les deux premières lignes du code que j'ai ajouté paramètrent deux variables dans le module partagé. De cette façon, quand le programme enfant démarre, les variables sont déjà présentes et peuvent être écrites quand on en a besoin. Nous utilisons aussi ces variables dans la fonction suivante ; c'est pourquoi nous devons les paramétrer tout de suite. Si nous ne le faisons pas, Python sortira une erreur.
  
 **The next thing we do is assign an alias for the status label, which is the red square that shows when the child program is running and connected to the shared module. Finally, I set up a timer function that Tkinter provides called “root.after”. This is an event that fires every X milliseconds to take care of just about any kind of repetitive task you want to do. You can also create multiple ‘root.after’ timers that run simultaneously. The basic syntax is: **The next thing we do is assign an alias for the status label, which is the red square that shows when the child program is running and connected to the shared module. Finally, I set up a timer function that Tkinter provides called “root.after”. This is an event that fires every X milliseconds to take care of just about any kind of repetitive task you want to do. You can also create multiple ‘root.after’ timers that run simultaneously. The basic syntax is:
Ligne 116: Ligne 116:
 In the case above, the handle is called “comm1” which lets me know that this particular timer is used to communicate with the child process. Notice that I set the time to 0, which means that the callback function will be called immediately, and the final parameter is the name of the callback function.** In the case above, the handle is called “comm1” which lets me know that this particular timer is used to communicate with the child process. Notice that I set the time to 0, which means that the callback function will be called immediately, and the final parameter is the name of the callback function.**
  
-Ensuite nous assignons un alias à l'étiquette d'état, qui est le carré rouge qui montre quand le programme enfant tourne et qu'il est connecté au module partagé. Enfin, j'ai paramétré une fonction compteur que Tkinter fournit sous le nom « root.after ». C'est un évènement qui se déclenche toutes les X millisecondes pour s'occuper de toutes les sortes de tâches répétitives que vous voulez faire. Vous pouvez aussi créer plusieurs compteurs « root.after » qui tournent en parallèle. La syntaxe de base est :+Ensuitenous assignons un alias à l'étiquette d'état, qui est le carré rouge qui montre quand le programme enfant tourne et qu'il est connecté au module partagé. Enfin, j'ai paramétré une fonction compteur que Tkinter fournit sous le nom « root.after ». C'est un événement qui se déclenche toutes les X millisecondes pour s'occuper de toutes les sortes de tâches répétitives que vous voulez accomplir. Vous pouvez aussi créer plusieurs compteurs « root.after » qui tournent en parallèle. La syntaxe de base est :
  
      handle = root.after(ms, callback)      handle = root.after(ms, callback)
            
-Dans le cas du dessus, le handle est appelé « comm1 » ce qui vous fait savoir que ce compteur particulier est utilisé pour communiquer avec le traitement enfant. Notez que j'ai réglé le temps sur 0, ce qui signifie que la fonction de rappel est appelée immédiatement et le paramètre final est le nom de la fonction de rappel.+Dans le cas ci-dessus, le handle est appelé « comm1 » ce qui vous fait savoir que ce compteur particulier est utilisé pour communiquer avec le traitement enfant. Notez que j'ai réglé le temps sur 0, ce qui signifie que la fonction de rappel est appelée immédiatement et le paramètre final est le nom de la fonction de rappel.
  
 **Bottom right is the callback function code… **Bottom right is the callback function code…
Ligne 126: Ligne 126:
 First, we set two global variables, comm1 which is the handle for the timer, and LblStat which is the alias for our little red square. Next, we access the shared module to see if the child process is running by checking shared.child_active to see if it’s True. This is set as soon as the child program starts up. If it is, we set the square colored label to “Green” to show that the child process is running and then we check to see if shared.ReadyToRead is set to True – which is basically a flag that says that one of the numeric keys has been clicked. If it is, we get that data, put it into the display label with the .set() method, and clear the ReadyToRead flag, so we can wait for the next click event on the child process. If the shared.child_active flag is False, we reset the coloured square to Red. This way, when the child program is exited, we will know it visually.** First, we set two global variables, comm1 which is the handle for the timer, and LblStat which is the alias for our little red square. Next, we access the shared module to see if the child process is running by checking shared.child_active to see if it’s True. This is set as soon as the child program starts up. If it is, we set the square colored label to “Green” to show that the child process is running and then we check to see if shared.ReadyToRead is set to True – which is basically a flag that says that one of the numeric keys has been clicked. If it is, we get that data, put it into the display label with the .set() method, and clear the ReadyToRead flag, so we can wait for the next click event on the child process. If the shared.child_active flag is False, we reset the coloured square to Red. This way, when the child program is exited, we will know it visually.**
  
-En bas à droite, voici le code de la focntion de rappel...+En bas à droite, voici le code de la fonction de rappel :
  
-D'abord, nous paramétrons deux variables globales, comm1 qui est le handle du compteuret LblStat qui est l'alias de notre petit carré rouge. Ensuite, nous accédons au module partagé pour voir si le processus enfant tourne en vérifiant shared.child_active pour voir s'il vaut True (Vrai). Il est ainsi dès que le programme enfant démarre. Si c'est la cas, nous réglons le carré coloré sur « Green » (Vert) pour montrer que le programe enfant tourne, et, ensuite, nous vérifions si shared.ReadyToRead est positionné sur True - c'est en gros un drapeau qui dit qu'une des touches numériques a été cliquée. Si c'est le cas, nous recevons les données, les mettons dans l'étiquette d'affichage avec la méthode .set() et effaçons le drapeau ReadyToRead de façon à attendre le prochain évènement de clic dans le processus enfant. Si le drapeau shared.child_active est False (Faux), nous remettons la couleur du carré à Red (Rouge). De cette façon, quand on sortira du programme enfant, nous le saurons visuellement.+D'abord, nous paramétrons deux variables globales, comm1 qui est le handle du compteur et LblStat qui est l'alias de notre petit carré rouge. Ensuite, nous accédons au module partagé pour voir si le processus enfant tourne en vérifiant si shared.child_active vaut True (Vrai). Il en est ainsi dès que le programme enfant démarre. Si c'est le cas, nous réglons le carré coloré sur « Green » (Vert) pour montrer que le programe enfant tourne, puis nous vérifions si shared.ReadyToRead est positionné sur True - c'est en gros un drapeau qui dit qu'une des touches numériques a été cliquée. Si c'est le cas, nous recevons les données, les mettons dans l'étiquette d'affichage avec la méthode .set() et effaçons le drapeau ReadyToRead de façon à attendre le prochain événement de clic dans le processus enfant. Si le drapeau shared.child_active est False (Faux), nous remettons la couleur du carré à Red (Rouge). De cette façon, quand le programme enfant se terminera, nous le saurons visuellement.
  
 **Finally, we “re-arm” the timer routine, this time to check 100 ms from that point. **Finally, we “re-arm” the timer routine, this time to check 100 ms from that point.
Ligne 138: Ligne 138:
 Enfin, nous « ré-armons » la routine du compteur, cette fois-ci pour décompter 100 ms à partir de là. Enfin, nous « ré-armons » la routine du compteur, cette fois-ci pour décompter 100 ms à partir de là.
  
-Maintenant, nous regardons la fonction de rappel on_btnExit (présentée ci-dessus). Elle est très simple. Nous appelons simplement la fonction destroy_window() qui terminera proprement le programme. La focntion destroy_window() est fournie par Page comme épine dorsale du rappel on_btnExit, car nous ajoutons le nom du rappel dans l'attribut de commande du bouton Exit. Tout ce que nous aovns à faire est d'ajouter la ligne « destroy_window() ».+Maintenant, nous regardons la fonction de rappel on_btnExit (présentée ci-dessus). Elle est très simple. Nous appelons simplement la fonction destroy_window() qui terminera proprement le programme. La fonction destroy_window() est fournie par Page tout comme l'épine dorsale du rappel on_btnExit, puisque nous avons ajouté le nom du rappel dans l'attribut de commande du bouton Exit. Tout ce que nous devons faire est d'ajouter la ligne « destroy_window() ».
  
-Ensuite, Nous regarderons la fonction de rappel btnLaunch (ci-dessus). C'est par là que nous démarrons le programme enfant. À nouveau, nous utilisons l'attribut de commande du bouton dans Page, de sorte que la structure générale est prête pour nous.+Ensuite, nous regardons la fonction de rappel btnLaunch (ci-dessus). C'est par là que nous démarrons le programme enfant. À nouveau, nous utilisons l'attribut de commande du bouton dans Page, de sorte que la structure générale est prête pour nous.
  
 **The only line we need to enter here is the last one. Since we have already imported the child.py GUI file at the top of the code, we just need to call the create_Toplevel1() function. This is the entry point for the program when it is called from another program. **The only line we need to enter here is the last one. Since we have already imported the child.py GUI file at the top of the code, we just need to call the create_Toplevel1() function. This is the entry point for the program when it is called from another program.
Ligne 148: Ligne 148:
 Now we’ll look at the child program. It is a bit more complicated, but not overly so. Again, I’m going to provide the code here for only the child_support.py module.** Now we’ll look at the child program. It is a bit more complicated, but not overly so. Again, I’m going to provide the code here for only the child_support.py module.**
  
-La seule ligne que nous avons besoin de saisir ici est le dernière. Comme nous aovns déjà importé le fichier d'affichage graphique child.py en haut du code, nous devons simplement appeler la fonction create_Toplevel1(). C'et le point d'entrée du programme quand il est appelé par un autre programme.+La seule ligne que nous avons besoin de saisir ici est la dernière. Comme nous avons déjà importé le fichier d'affichage graphique child.py au début du code, nous devons simplement appeler la fonction create_Toplevel1(). C'est le point d'entrée du programme quand il est appelé par un autre programme.
  
-Enfin, j'ai mis destroy_window() (ci-dessous), fournie par Page, jouste pour que vous la voyez.+Enfin, j'ai mis destroy_window() (ci-dessous), fournie par Page, juste pour que vous la voyiez.
  
 Maintenant, nous regardons le programme enfant. Il est un peut plus compliqué, mais pas trop. Ici encore, je vais fournir le code uniquement pour le module child_support.py. Maintenant, nous regardons le programme enfant. Il est un peut plus compliqué, mais pas trop. Ici encore, je vais fournir le code uniquement pour le module child_support.py.
Ligne 163: Ligne 163:
  
 The first thing we do is set up a global variable to hold the accumulated value of the keypad entries. We then call the function setup_bindings() that attaches the callback function to all of the buttons of the keypad. Finally, we set the shared.child_active flag to True.** The first thing we do is set up a global variable to hold the accumulated value of the keypad entries. We then call the function setup_bindings() that attaches the callback function to all of the buttons of the keypad. Finally, we set the shared.child_active flag to True.**
 +
 +À nouveau, nous commençons par la section des imports. Notez ici que nous ne devons importer que le module partagé, car nous n'avons besoin d'appeler aucune fonction du parent.
 +
 +import sys
 +
 +import shared
 +
 +En haut à droite, voici la définition de l'étiquette qui montre la valeur courante venant des saisies sur les boutons du pavé numérique :
 +
 +La première chose que nous faisons est de paramétrer une variable globale pour garder la valeur cumulative des saisies du pavé. Ensuite, nous appelons la fonction setup_bindings() qui relie la fonction de rappel à tous les boutons du pavé. Enfin, nous paramétrons le drapeau shared.child_active à True.
  
 **Since we are going to pass parameters to the callback for the keypad buttons, it’s much easier to deal with things here (below) than to try to do it within Page through the command attribute. **Since we are going to pass parameters to the callback for the keypad buttons, it’s much easier to deal with things here (below) than to try to do it within Page through the command attribute.
Ligne 169: Ligne 179:
  
 In the callback, we simply take the value (which is the number of the button) and append it, as a string, to the valu variable. We also check to see if the period key (value 10) was pressed, and if it was, then we add the period into the display value. Finally, we put the data into the DisplayLabel through the .set() method, and set shared.ReadyToRead to True, so the parent knows to pull the data.** In the callback, we simply take the value (which is the number of the button) and append it, as a string, to the valu variable. We also check to see if the period key (value 10) was pressed, and if it was, then we add the period into the display value. Finally, we put the data into the DisplayLabel through the .set() method, and set shared.ReadyToRead to True, so the parent knows to pull the data.**
 +
 +Comme nous allons passer des paramètres à la fonction de rappel des boutons du pavé, il est plus facile de s'arranger avec les choses ici (ci-dessous) plutôt que d'essayer de le faire dans Page par le biais de l'attribut de commande.
 +
 +Maintenant, nous définissons le code de la routine de rappel (page suivante, en haut à gauche) dans le cas où on aurait cliqué sur un bouton du pavé. Notez qu'il faut le faire à partir de zéro, car Page n'a aucune idée de la nécessité de cette fonction.
 +
 +Dans la fonction de rappel, nous prenons simplement la valeur (qui est le numéro du bouton) et le rajoutons, sous forme de chaîne, à la variable valu. Nous vérifions aussi si la touche du point (valeur 10) a été enfoncée, et, si c'est le cas, nous ajoutons le point à la valeur affichée. Enfin, nous mettons les données dans DisplayLabel par la méthode .set(), et réglons shared.ReadyToRead à True, de sorte que le parent sait qu'il doit récupérer les données.
  
 **We don’t do anything with the Enter button, so we just leave the skeleton for later use (far right). **We don’t do anything with the Enter button, so we just leave the skeleton for later use (far right).
Ligne 185: Ligne 201:
  
 Until next time, keep coding.** Until next time, keep coding.**
 +
 +Nous ne faisons rien du bouton Entrée ; aussi, nous gardons juste la structure pour un usage ultérieur (à droite, en haut).
 +
 +Comme d'habitude, j'ai mis le code des programmes sur Pastebin. Voici les liens ci-dessous :
 +
 +parent.py - https://pastebin.com/AZXXvuAU
 +
 +parent_support.py - https://pastebin.com/3iBHgCN0
 +
 +child.py - https://pastebin.com/bwZLnkHc
 +
 +child_support.py - https://pastebin.com/Vg0K1w5G
 +
 +J'espère que cet article vous a donné de la matière à réflexion utile susceptible de vous aider dans votre propre programmation.
 +
 +Jusqu'à la prochaine fois, continuez à coder !
 +
 +p 26, col 4, encart, lignes noires :
 +
 +**Here is the init function from the child program. Again, you can see where my code starts.**
 +
 +Voici la fonction init du programme enfant. À nouveau, vous pouvez voir où commence mon code.
 +
 +p 25, col 4, encart, 3 § noirs :
 +
 +**The callback for the Exit button is mostly the same as for the parent, but we also set shared.child_active to False, so the Parent knows to change the status square from Green to Red and not to try to poll.**
 +
 +La fonction de rappel du bouton Exit est principalement la même que pour le parent, mais nous réglons aussi shared.child_active à False, de sorte que le parent sait qu'il doit changer le carré du vert au rouge et ne plus essayer de l'interroger.
 +
 +**The btnClear callback function sets the global valu to an empty string, sets data into the shared module and the display label, and then sets the shared.ReadyToRead flag to True.**
 +
 +La fonction de rappel btnClear charge la globale valu avec une chaîne vide, règle les données dans le module partagé et l'étiquette d'affichage, puis positionne le drapeau ReadyToRead à True.
 +
 +**Finally, we deal with the callback for the Backspace button. We simply strip the last character from the valu string, display it, pass it to the shared module, and set the flag so that the parent program will read it.**
 +
 +Enfin, nous nous occupons de la fonction de rappel du bouton Backspace (Retour Arrière). Nous supprimons juste le dernier caractère de la chaîne valu, l'affichons, la passons au module partagé et réglons le drapeau de sorte que le programme parent la lise.
 +
issue155/python.1585897086.txt.gz · Dernière modification : 2020/04/03 08:58 de d52fr