Formation PUB400 : Python, 2018 Environnement graphique tkinter

9.20 Liste déroulante (Combobox)


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.

Données de la 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 :

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.

Données statiques

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 :

Python

dictionnaire_des_couleurs = {

    '1': 'rouge',

    '2': 'bleu',

    '3': 'vert'

}

Données tirées de la base de données

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 :

Python

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 :

Résultat à l'écran

{3: 'Claviers', 1: 'Écrans', 2: 'Souris'}

Élément ajouté au début de la liste déroulante

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 :

Python

dictionnaire_des_categories = {'': 'Veillez choisir...'}

Combobox avec Veuillez choisir

Vous avez dit valeur ?

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.

clé et valeur dans un dictionnaire

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.

valeur et libellé dans une liste déroulante

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.

États du Combobox

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 :

  • enabled : le Combobox est activé complètement et permet la saisie de texte ou encore d'effectuer un choix dans la liste déroulante.
  • readonly : le Combobox est partiellement activé. Il est possible de choisir un item dans la liste déroulante mais pas d'y saisir du texte.
  • disabled : le Combobox est désactivé.

Ajouter les données dans la liste déroulante

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 :

Python

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 :

Résultat à l'écran

('Veuillez choisir...', 'Claviers', 'Écrans', 'Souris')

Sélectionner un élément par programmation

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 :

Python

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.

Retrouver l'index à partir du libellé

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 :

Python

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)

Retrouver l'index à partir de la clé étrangère

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é.

Python

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)

Retrouver la clé étrangère qui correspond à l'élément sélectionné

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 :

Python

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 :

Python

categorie_id = retrouver_cle(dictionnaire_des_categories, categorie.get())

▼Publicité

Veuillez noter que le contenu de cette fiche vous est partagé à titre gracieux, au meilleur de mes connaissances et sans aucune garantie.
Merci de partager !
Soumettre