issue155:python
Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédente | Dernière révisionLes deux révisions suivantes | ||
issue155:python [2020/04/04 07:52] – d52fr | issue155:python [2020/04/04 11:59] – auntiee | ||
---|---|---|---|
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, | + | Une rapide mise à jour à propos de la bibliothèque recipe-scrapers dont j'ai parlé le mois dernier. Actuellement, |
- | Comme la plupart d' | + | Comme la plupart d' |
**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' | + | Parmi toutes les questions que je reçois sur l' |
- | Aussi, j'ai pensé mettre sur pied une rapide démo en utilisant Page pour montrer comment | + | Aussi, j'ai pensé mettre sur pied une rapide démo en utilisant Page pour montrer comment |
Le projet sera constitué de deux formulaires Page, l'un appelé « Parent », l' | Le projet sera constitué de deux formulaires Page, l'un appelé « Parent », l' | ||
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 dynamiques ; l'une est un simple carré coloré qui montre l' | + | 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' |
- | btnLaunch a l' | + | btnLaunch a l' |
**Next, we’ll design our child program. This one is a bit more complicated, | **Next, we’ll design our child program. This one is a bit more complicated, | ||
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 | + | 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 |
Les trois boutons complémentaires ont leurs attributs de commande paramétrés sur on_btnClear, | Les trois boutons complémentaires ont leurs attributs de commande paramétrés sur on_btnClear, | ||
- | Les 11 boutons du pavé n' | + | Les 11 boutons du pavé n' |
**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, | + | 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, |
Malgré tout, vous devez rester prudent pour vous assurer que, avant d' | Malgré tout, vous devez rester prudent pour vous assurer que, avant d' | ||
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' | + | 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' |
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. | 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. | ||
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, | 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, | ||
- | Ensuite, nous assignons un alias à l' | + | Ensuite, nous assignons un alias à l' |
| | ||
Ligne 128: | Ligne 128: | ||
En bas à droite, voici le code de la fonction de rappel... | En bas à droite, voici le code de la fonction de rappel... | ||
- | D' | + | D' |
**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 fonction destroy_window() est fournie par Page comme épine dorsale du rappel on_btnExit, | + | 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, |
- | Ensuite, | + | Ensuite, |
**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, | Now we’ll look at the child program. It is a bit more complicated, | ||
- | La seule ligne que nous avons besoin de saisir ici est la dernière. Comme nous avons déjà importé le fichier d' | + | La seule ligne que nous avons besoin de saisir ici est la dernière. Comme nous avons déjà importé le fichier d' |
- | Enfin, j'ai mis destroy_window() (ci-dessous), | + | Enfin, j'ai mis destroy_window() (ci-dessous), |
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 164: | Ligne 164: | ||
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' | + | À nouveau, nous commençons par la section des imports. Notez ici que nous ne devons importer que le module partagé, car nous n' |
import sys | import sys | ||
Ligne 170: | Ligne 170: | ||
import shared | import shared | ||
- | En haut à droite, voici la définition de l' | + | En haut à droite, voici la définition de l' |
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. | 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. | ||
Ligne 180: | Ligne 180: | ||
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' | + | Comme nous allons passer des paramètres à la fonction de rappel des boutons du pavé, il est plus facile de s' |
- | Maintenant, nous définissons le code de la routine de rappel (page suivante, en haut à gauche) dans le cas où un bouton du pavé serait cliqué. Notez que c'est mieux fait à partir de zéro, car Page n'a aucune idée des besoins pour cette fonction. | + | 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é pressée, et, si c' | + | 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' |
**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 214: | Ligne 214: | ||
child_support.py - https:// | child_support.py - https:// | ||
- | J' | + | J' |
Jusqu' | Jusqu' | ||
Ligne 220: | Ligne 220: | ||
p 26, col 4, encart, lignes noires : | p 26, col 4, encart, lignes noires : | ||
- | **Here is the init function from the child program. Again, you can see where my code starts.* | + | **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. | Voici la fonction init du programme enfant. À nouveau, vous pouvez voir où commence mon code. | ||
Ligne 228: | Ligne 228: | ||
**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.** | **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 | + | 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 |
**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.** | **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' | + | 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' |
**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.** | **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 Retour Arrière. Nous supprimons juste le dernier caractère de la chaîne, l' | + | Enfin, nous nous occupons de la fonction de rappel du bouton |
issue155/python.txt · Dernière modification : 2020/04/04 18:00 de andre_domenech