Les deux révisions précédentesRévision précédente | |
issue197:python [2023/10/01 18:08] – d52fr | issue197:python [2023/10/02 15:38] (Version actuelle) – auntiee |
---|
Comme le titre de l'article l'indique, je vais encore parler de PAGE. Cette fois, je vais vous montrer comment pousser l'enveloppe et ajouter des widgets Tcl SANS utiliser de widget personnalisé. | Comme le titre de l'article l'indique, je vais encore parler de PAGE. Cette fois, je vais vous montrer comment pousser l'enveloppe et ajouter des widgets Tcl SANS utiliser de widget personnalisé. |
| |
Si vous êtes un tant soit peu familier avec PAGE, vous savez peut-être qu'il y a quelques widgets « normaux » que PAGE n'inclut pas dans sa boîte à outils. Bien que cela laisse un vide dans PAGE et son ensemble de widgets que vous pouvez utiliser, il n'y a jamais eu une grande demande de support pour ces widgets, ce qui est une des raisons pour lesquelles ils n'ont pas été ajoutés avant aujourd'hui. | Si vous connaissez un tant soit peu PAGE, vous savez peut-être qu'il y a quelques widgets « normaux » que PAGE n'inclut pas dans sa boîte à outils. Bien que cela laisse un vide dans PAGE et son ensemble de widgets que vous pouvez utiliser, il n'y a jamais eu une grande demande de support pour ces widgets, ce qui est une des raisons pour lesquelles ils n'ont pas été ajoutés auparavant. |
| |
De quels widgets s'agit-il ? Les widgets Menubutton et OptionMenu. | De quels widgets s'agit-il ? Les widgets Menubutton et OptionMenu. |
Le widget Menubutton revient à disposer d'un menu normal de type barre de menu, mais sur un bouton. | Le widget Menubutton revient à disposer d'un menu normal de type barre de menu, mais sur un bouton. |
| |
Vous pouvez utiliser tous les éléments de menu « normaux » sur un Menubutton. Cela inclut la cascade, les commandes, les séparateurs, les boutons de contrôle et les boutons radios. En outre, vous pouvez inclure des accélérateurs, des images et créer des sauts de colonne. | Vous pouvez utiliser tous les éléments de menu « normaux » sur un Menubutton. Cela inclut la cascade, les commandes, les séparateurs, les boutons à cocher et les boutons radios. En outre, vous pouvez inclure des accélérateurs, des images et créer des sauts de colonne. |
| |
L'image ci-dessus montre un très long ensemble d'options de bouton de menu qui représente tous les livres de la version King James de la Bible, regroupés en livres de l'Ancien Testament et livres du Nouveau Testament, séparés par un saut de colonne, et chaque colonne a un « en-tête » qui est composé d'un élément de menu désactivé. Chaque élément de menu est un bouton radio qui renvoie immédiatement une valeur entière qui peut être consultée dans la liste qui a créé le menu représentant la sélection effectuée par l'utilisateur. | L'image ci-dessus montre un très long ensemble d'options de bouton de menu qui représente tous les livres de la version King James de la Bible, regroupés en livres de l'Ancien Testament et livres du Nouveau Testament, séparés par un saut de colonne, et chaque colonne a un « en-tête » qui est composé d'un élément de menu désactivé. Chaque élément de menu est un bouton radio qui renvoie immédiatement une valeur entière qui peut être consultée dans la liste qui a créé le menu représentant la sélection effectuée par l'utilisateur. |
J'ai en fait créé deux projets assez similaires pour ce mois-ci, mais je ne vais passer en revue qu'un seul d'entre eux. (Vous entendez Ronnie pousser un soupir de soulagement ?) Cependant, je vais les inclure tous les deux dans le dépôt du mois. Celui que nous allons étudier ici est un projet simple qui peut être trouvé dans le dépôt sous le nom de « mb_om_demo.py ». Je ne m'étendrai pas trop sur la création du projet sous PAGE, car la façon dont je l'ai créé est assez évidente. | J'ai en fait créé deux projets assez similaires pour ce mois-ci, mais je ne vais passer en revue qu'un seul d'entre eux. (Vous entendez Ronnie pousser un soupir de soulagement ?) Cependant, je vais les inclure tous les deux dans le dépôt du mois. Celui que nous allons étudier ici est un projet simple qui peut être trouvé dans le dépôt sous le nom de « mb_om_demo.py ». Je ne m'étendrai pas trop sur la création du projet sous PAGE, car la façon dont je l'ai créé est assez évidente. |
| |
En gros, il y a quatre étiquettes (deux statiques et deux dynamiques), un bouton (le bouton Exit) et deux cadres. Les cadres sont les cases vides situées entre les deux séries d'étiquettes. J'ai utilisé le relief « solid » pour les cadres. Ainsi, lorsque vous concevez le formulaire, vous savez exactement où se trouvent les cadres. J'ai conçu le projet sous PAGE 7.6, le fichier .tcl est donc inclus. | En gros, il y a quatre étiquettes (deux statiques et deux dynamiques), un bouton (le bouton Exit) et deux cadres. Les cadres sont les cases vides situées entre les deux séries d'étiquettes. J'ai utilisé le relief « solid » pour les cadres. Ainsi, lorsque vous concevez le formulaire, vous savez exactement où se trouvent les cadres. J'ai conçu le projet sous PAGE 7.6 ; le fichier .tcl est donc inclus. |
| |
| |
The first thing we do to create the Menubutton widget is to define a couple of global variables, one for the carTypes, which we just defined in the setup_menubutton_items function, and the other named selection, which will be a type of tk.IntVar, since our menu items will all be of the radiobutton type. Then we set the frame relief from solid to flat, to make the frame invisible. Finally, we make the actual assignment of the tk.IntVar. Again, we will do this so the user’s selection will immediately be handled and to cut down on the number of callback functions. | The first thing we do to create the Menubutton widget is to define a couple of global variables, one for the carTypes, which we just defined in the setup_menubutton_items function, and the other named selection, which will be a type of tk.IntVar, since our menu items will all be of the radiobutton type. Then we set the frame relief from solid to flat, to make the frame invisible. Finally, we make the actual assignment of the tk.IntVar. Again, we will do this so the user’s selection will immediately be handled and to cut down on the number of callback functions. |
| |
Next, we create the actual widget. Then we will use the Pack geometry manager to “shove” the widget into the frame and force it to completely fill the frame. The name of the MenuButton instance is mnuBtn. We’ll use this every time we need to reference it. Notice that we don’t use the normal _w1. prefix, since we created this not PAGE. | Next, we create the actual widget. Then we will use the Pack geometry manager to “shove” the widget into the frame and force it to completely fill the frame. The name of the Menubutton instance is mnuBtn. We’ll use this every time we need to reference it. Notice that we don’t use the normal _w1. prefix, since we created this not PAGE. |
| |
mnuBtn = ttk.Menubutton(_w1.mbFrame, text="Items") | mnuBtn = ttk.Menubutton(_w1.mbFrame, text="Items") |
mnuBtn.pack(expand=True, side="top", fill="both", anchor="nw")** | mnuBtn.pack(expand=True, side="top", fill="both", anchor="nw")** |
| |
Une chose à noter ici. Les éléments du bouton de menu sont dans une liste. Les éléments de l'OptionMenu sont des tuple. C'est important, comme vous le verrez dans quelques instants. | Une chose à noter ici. Les éléments du Menubutton sont dans une liste. Les éléments de l'OptionMenu sont des tuple. C'est important, comme vous le verrez dans quelques instants. |
| |
Nous allons maintenant créer le widget Menubutton et le placer dans le cadre approprié (ci-dessous). | Nous allons maintenant créer le widget Menubutton et le placer dans le cadre approprié (ci-dessous). |
| |
La première chose à faire pour créer le widget Menubutton est de définir quelques variables globales, l'une pour les carTypes, que nous venons de définir dans la fonction setup_menubutton_items, et l'autre nommée selection, qui sera un type de tk.IntVar, puisque nos éléments de menu seront tous de type radiobutton. Ensuite, nous définissons le relief du cadre de solid à flat, pour rendre le cadre invisible. Enfin, nous procédons à l'affectation réelle de tk.IntVar. Encore une fois, nous faisons cela pour que la sélection de l'utilisateur soit immédiatement gérée et pour réduire le nombre de fonctions de rappel. | La première chose à faire pour créer le widget Menubutton est de définir quelques variables globales, l'une pour les carTypes, que nous venons de définir dans la fonction setup_menubutton_items, et l'autre nommée selection, qui sera un type de tk.IntVar, puisque nos éléments de menu seront tous de type radiobutton. Ensuite, nous définissons le relief du cadre de solid à flat, pour rendre le cadre invisible. Enfin, nous procédons à l'affectation réelle de tk.IntVar. Encore une fois, nous faisons cela pour que la sélection de l'utilisateur soit immédiatement traitéé et pour réduire le nombre de fonctions de rappel. |
| |
Ensuite, nous créons le widget proprement dit. Nous utiliserons ensuite le gestionnaire de géométrie Pack pour « pousser » le widget dans le cadre et le forcer à le remplir complètement. Le nom de l'instance du bouton de menu est mnuBtn. Nous l'utiliserons chaque fois que nous devrons y faire référence. Notez que nous n'utilisons pas le préfixe normal _w1. puisque nous l'avons créé en dehors de PAGE. | Ensuite, nous créons le widget proprement dit. Nous utiliserons ensuite le gestionnaire de géométrie Pack pour « pousser » le widget dans le cadre et le forcer à remplir le frame complètement. Le nom de l'instance du Menubutton est mnuBtn. Nous l'utiliserons chaque fois que nous devrons y faire référence. Notez que nous n'utilisons pas le préfixe normal _w1. puisque nous l'avons créé en dehors de PAGE. |
| |
mnuBtn = ttk.Menubutton(_w1.mbFrame, text="Items") | mnuBtn = ttk.Menubutton(_w1.mbFrame, text="Items") |
Maintenant (en haut à droite), nous devons définir l'objet menu qui sera attaché au bouton de menu. | Maintenant (en haut à droite), nous devons définir l'objet menu qui sera attaché au bouton de menu. |
| |
La dernière chose que nous faisons pour le bouton de menu est de définir une variable compteur, de parcourir la liste des types de voiture, puis de créer l'élément de menu radiobutton avec le nom du type de voiture, le rappel, la valeur de la variable compteur que nous définissons comme la valeur qui sera transmise au rappel, et le nom de la variable qui, dans notre cas, est la sélection. Enfin, en bas à droite, nous ajoutons un à la variable counter. | La dernière chose que nous faisons pour le Menubutton est de définir une variable compteur, de parcourir la liste des carTypes, puis de créer l'élément de menu radiobutton avec le nom du type de voiture, le rappel, la valeur de la variable compteur que nous définissons comme la valeur qui sera transmise au rappel, et le nom de la variable qui, dans notre cas, est la sélection. Enfin, en bas à droite, nous ajoutons un à la variable counter. |
| |
Nous commençons par le même type de code que pour le widget Menubutton. Nous définissons les globales, nous définissons le relief du cadre de solid à flat, et nous définissons tk.StringVar pour notre valeur de retour. | Nous commençons par le même type de code que pour le widget Menubutton. Nous définissons les globales, nous définissons le relief du cadre de solid à flat, et nous définissons tk.StringVar pour notre valeur de retour. |
If we were to use a straight list, the options will all be placed on the same line instead of a dropdown set of items. There might be a reason for you to want to do this, but I can’t imagine one (next page). | If we were to use a straight list, the options will all be placed on the same line instead of a dropdown set of items. There might be a reason for you to want to do this, but I can’t imagine one (next page). |
| |
That’s it. Now I have to say that the OptionMenu widget is REALLY a whole lot easier to deal with than the MenuButton. If you’ve ever created a menu by hand in Tkinter, you know it is not a painless process and often not worth all the work. You can see what I mean in the second project. If you run back to the first image in the article, you will see the Menubutton example. I really did this as a proof of concept more than for any real need. I would probably use a popup menu created in the PAGE menu editor before I would hand code a menu for a Menubutton.** | That’s it. Now I have to say that the OptionMenu widget is REALLY a whole lot easier to deal with than the Menubutton. If you’ve ever created a menu by hand in Tkinter, you know it is not a painless process and often not worth all the work. You can see what I mean in the second project. If you run back to the first image in the article, you will see the Menubutton example. I really did this as a proof of concept more than for any real need. I would probably use a popup menu created in the PAGE menu editor before I would hand code a menu for a Menubutton.** |
| |
Cependant, remarquez que dans les options du widget, nous utilisons *optionlist comme « liste » d'options à afficher. Rappelez-vous que j'ai dit que nous devions en faire un tuple, et non une liste. La raison en est que vous pouvez fournir chaque élément séparément, comme le montre la ligne de syntaxe ci-dessous... | Cependant, remarquez que dans les options du widget, nous utilisons *optionlist comme la « liste » d'options à afficher. Rappelez-vous que j'ai dit que nous devions en faire un tuple, et non une liste. La raison en est que vous pouvez fournir chaque élément séparément, comme le montre la ligne de syntaxe ci-dessous... |
| |
w = ttk.OptionMenu(parent, variable, choix 1 , choix 2 , ...) | w = ttk.OptionMenu(parent, variable, choix 1 , choix 2 , ...) |
| |
Si nous devions utiliser une liste directe, les options seraient toutes placées sur la même ligne au lieu d'un ensemble d'éléments déroulants. Vous pourriez avoir une raison de vouloir faire cela, mais je n'en vois pas (page suivante). | Si nous devions utiliser une véritable liste, les options seraient toutes placées sur la même ligne au lieu d'un ensemble d'éléments déroulants. Vous pourriez avoir une raison de vouloir faire cela, mais je n'en vois pas (page suivante). |
| |
Voilà, c'est fait. Je dois dire que le widget OptionMenu est VRAIMENT beaucoup plus facile à utiliser que MenuButton. Si vous avez déjà créé un menu à la main dans Tkinter, vous savez que ce n'est pas un processus sans douleur et qu'il ne vaut souvent pas la peine d'y consacrer tout son temps. Vous pouvez voir ce que je veux dire dans le deuxième projet. Si vous revenez à la première image de l'article, vous verrez l'exemple du Menubutton. J'ai vraiment fait cela comme une preuve de concept plus que pour un besoin réel. J'utiliserais probablement un menu contextuel créé dans l'éditeur de menu PAGE avant de coder à la main un menu pour un Menubutton. | Voilà, c'est fait. Je dois dire que le widget OptionMenu est VRAIMENT beaucoup plus facile à utiliser que Menubutton. Si vous avez déjà créé un menu à la main dans Tkinter, vous savez que ce n'est pas un processus sans douleur et qu'il ne vaut souvent pas la peine d'y consacrer tout son temps. Vous pouvez voir ce que je veux dire dans le deuxième projet. Si vous revenez à la première image de l'article, vous verrez l'exemple du Menubutton. J'ai vraiment fait cela comme une preuve de concept plus que pour un besoin réel. J'utiliserais probablement un menu contextuel créé dans l'éditeur de menu PAGE avant de coder à la main un menu pour un Menubutton. |
| |
| |
Le but de ce projet était de vous montrer qu'avec un peu de travail (enfin, BEAUCOUP de travail dans le cas du Menubutton) et en creusant, vous pouvez utiliser n'importe quel widget fourni par Tkinter même si PAGE ne le prend pas en charge. | Le but de ce projet était de vous montrer qu'avec un peu de travail (enfin, BEAUCOUP de travail dans le cas du Menubutton) et en creusant, vous pouvez utiliser n'importe quel widget fourni par Tkinter même si PAGE ne le prend pas en charge. |
| |
J'ai mis le code du projet de ce mois dans un dépôt github à https://github.com/gregwa1953/FCM-197. | J'ai mis le code du projet de ce mois-ci dans un dépôt github à https://github.com/gregwa1953/FCM-197. |
| |
Jusqu'à la prochaine fois, comme toujours, restez en sécurité, en bonne santé, positifs et créatifs ! | Jusqu'à la prochaine fois, comme toujours, restez en sécurité, en bonne santé, positifs et créatifs ! |
| |