Le widget Combobox permet de générer une liste déroulante dans une application graphique avec tkinter.
Avant de se lancer tête baissée dans l'utilisation du Combobox, il est important de bien comprendre les principes de base d'une liste déroulante.
Une liste déroulante est composée d'une série d'éléments pour lesquels on retrouve un libellé et une valeur. La valeur indique ce que vaudra la liste déroulante lorsque l'usager cliquera sur un libellé. La valeur n'est jamais affichée.
Dans certains langages de programmation ou de balisage, la valeur fait partie intégrante de la liste déroulante.
Par exemple, en HTML :
<select id="voiture" name="voiture" size="1" >
<option value="2">Ford Escape</option>
<option value="4">Honda Civic</option>
<option value="1">Mazda 5</option>
<option value="3">Mini Cooper</option>
<option value="5">Toyota Matrix</option>
</select>
Avec tkinter, le widget Combobox ne gère pas du tout les valeurs. Pour lui, le libellé et la valeur ne font qu'un.
Pour pouvoir retrouver la valeur associée à un libellé, on utilisera un tableau associatif, également appelé dictionnaire.
Il est possible d'utiliser des données statiques pour remplir une liste déroulante.
Par exemple, pour une liste déroulante qui permet de choisir une couleur, on pourra utiliser le dictionnaire suivant :
dictionnaire_des_couleurs = {
'1': 'rouge',
'2': 'bleu',
'3': 'vert'
}
Dans certains contextes, les données doivent être tirés d'une table de la base de données. Par exemple, si on a une relation de un à plusieurs entre les produits et les catégories, la catégorie du produit sera sélectionnée à l'aide d'une liste déroulante dont les données sont tirées de la table des catégories.
Dans un tel cas, la valeur de chaque élément correspondra à la clé primaire de la catégorie et le libellé, à sa description.
Les données de la liste déroulante pourront être initialisées comme suit :
requete = 'SELECT id, description FROM categories ORDER BY description'
curseur.execute(requete)
resultat = curseur.fetchall()
dictionnaire_des_categories = {} # crée un dictionnaire vide
for enreg in resultat:
dictionnaire_des_categories[enreg[0]] = enreg[1]
Si on fait afficher la variable dictionnaire_des_categories à la console, on obtiendra quelque chose du genre :
{3: 'Claviers', 1: 'Écrans', 2: 'Souris'}
Il peut être intéressant d'ajouter un élément dans le haut de la liste déroulante pour inviter l'utilisateur à effectuer une sélection.
Pour y parvenir, il suffit d'initialiser le dictionnaire avec un élément prédéfini avant de boucler dans les résultats de la requête. On laissera généralement la valeur à blanc pour cet élément.
Ex :
dictionnaire_des_categories = {'': 'Veillez choisir...'}

Attention au vocabulaire : le terme valeur a une signification différente dans un dictionnaire et dans une liste déroulante.
Dans un dictionnaire, la valeur correspond à l'information qui peut être retrouvée à partir de la clé.
Les dictionnaires dont les données proviennent de la base de données seront généralement créés comme suit : la clé primaire de chaque enregistrement jouera le rôle de clé et la description sera la valeur.

Dans une liste déroulante, la valeur (qui n'est pas affichée) correspond à ce que vaut un libellé.
Dans ce contexte, la clé primaire correspond à la valeur.

Le widget Combobox déroge légèrement à cette règle puisque les libellés affichés dans le Combobox sont initialisées à l'aide de l'attribut values, qui correspond en fait aux valeurs du dictionnaire.
Un Combobox (combo est l'abréviation de combinaison) est la combinaison d'une zone de texte et d'un menu déroulant. Le Combobox permet donc d'entrer n'importe quelle valeur au clavier ou encore de choisir un item parmi la liste proposée.
Ce comportement peut être ajusté à l'aide de l'attribut state qui indique l'état du widget.
Les états qui nous intéressent ici sont :
L'attribut values du Combobox doit être initialisé avec un tableau des données à afficher.
Attention : ce sont les libellés qui sont ajoutés dans le Combobox même si l'attribut s'appelle values. Les valeurs ne sont pas affichées ni même gérées par le widget.
Puisque le widget Combobox ne gère pas les valeurs, on doit extraire les libellés du dictionnaire sous forme de tableau.
Tout d'abord, pour extraire les valeurs d'un dictionnaire, on utilisera la fonction values(). On convertira le résultat en tableau à l'aide de la fonction list().
Ex :
from tkinter import *
from tkinter.ttk import *
...
categorie = Combobox(fenetre, state='readonly') # on ne veut pas permettre d'entrer autre chose qu'un élément de la liste
categorie['values'] = list(dictionnaire_des_categories.values())
categories.pack()
Si on fait afficher categorie['values'] à la console, on obtiendra quelque chose du genre :
('Veuillez choisir...', 'Claviers', 'Écrans', 'Souris')
La fonction current() permet de déterminer ce qui sera sélectionné par défaut dans la liste déroulante. Elle prend en paramètre l'index (la position) de l'élément à sélectionner.
Par exemple, pour sélectionner le premier élément de la liste :
categorie.current(0)
La sélection par défaut dans un Combobox est particulièrement importante lorsqu'on doit modifier un enregistrement existant.
On sait que pour chacun des champs dont la valeur est saisie dans un widget Entry, le widget sera initialisé avec la valeur qui est actuellement dans la base de données.
Dans le cas d'une clé étrangère, il faudra que le Combobox qui lui est associé affiche le libellé qui correspond à cette clé étrangère. Par exemple, si un produit fait partie de la catégorie 2, qui correspond à une souris, il faudra que le Combobox affiche par défaut Souris.
La fonction index() permet de retrouver la position d'un élément dans un tableau.
Si on connaît le libellé qui correspond à l'élément qui doit être sélectionné, on pourra travailler directement avec le tableau des libellés du Combobox (categorie['values']). La fonction index() recevra en paramètre le libellé recherché.
Ex :
libelle = ... # donnée de départ = libellé qui correspond à la clé étrangère pour l'enregistrement à modifier
index = categorie['values'].index(libelle)
categorie.current(index)
Une clé étrangère, qui correspond à une clé dans un dictionnaire, n'est pas affichée ni même gérée par le Combobox.
Dans le cas où la clé étrangère est la seule information dont nous disposons pour sélectionner l'élément correspondant dans le Combobox, il faudra passer par le dictionnaire pour retrouver sa position.
Le dictionnaire est conçu pour retrouver la valeur d'un élément (donc le libellé du Combobox) qui correspond à une clé. On pourra ensuite retrouver l'index à partir du libellé.
categorie_id = ... # donnée de départ = clé étrangère de l'enregistrement à modifier
libelle = dictionnaire_des_categories[categorie_id]
index = categorie['values'].index(libelle)
categorie.current(index)
Une fois qu'un élément a été sélectionné par l'usager dans le Combobox, on peut retrouver le libellé sélectionné à l'aide de get(), tout comme on le faisait avec un Entry.
Ex :
libelle = categorie.get()
Pour procéder à l'enregistrement des informations, on devra retrouver la clé étrangère à partir de ce libellé. Ici encore, c'est le dictionnaire qui permettra de faire le lien entre ces deux informations.
On sait que le fonctionnement normal d'un dictionnaire consiste à retrouver une valeur à partir d'une clé. Ici, on doit faire exactement l'inverse, c'est-à-dire retrouver la clé du dictionnaire (la clé étrangère) à partir d'une valeur (le libellé).
Grâce à la fonction retrouver_cle() que je vous ai fournie, on pourra retrouver la clé étrangère à partir du libellé sélectionné dans le Combobox :
categorie_id = retrouver_cle(dictionnaire_des_categories, categorie.get())
▼Publicité