Logo Python

[Python – Tkinter] Liste déroulante avec Combobox, le chemin de croix.

Bannière PythonPython 3, c’est le bien. Les interfaces graphiques, c’est ergonomique. Tant qu’on reste dans les standards, on se dit que tout sera supporté, qu’il y aura de la belle documentation. Et bien je dois dire que pour arriver à avoir une liste déroulante, j’ai du secouer mon ami Google.

La recherche

Au départ, j’ai cru trouver la solution dans la documentation de Tkinter (enfin, une des documentations, il n’y a apparemment rien de bien concis à ce niveau). Peine perdue. Compliqué à trouver, lire et à s’y retrouver. Me disant que c’était juste une bête chose, un bête nom de widget, je tape sur Google (mais pas trop fort) : « liste déroulante + tkinter« . Mauvaise idée, en voyant les résultats de la première page je me suis rappelé que les recherches anglaises sont bien plus fructueuses (un stackoverflow en français, ça existe ?), me voici donc parti avec « dropdown menu + tkinter + python 3« . Sans entrer dans les détails, voici les différents résultats que j’ai pu avoir :

Ouais, ouais, pas fameux quoi. J’ai même failli me résoudre à utiliser ces méthodes visiblement généralisée, mais après une pause d’une semaine sans le net, on retrouve de la force et de la ténacité.

Révélation

En cherchant d’autres modules de GUI pour le python pour d’autres projets, je suis tombé sur le blog d’une personne aimant s’amuser avec python et qui partage ses découvertes et ses savoirs. Comme ici, au final. Mais avec bien plus de contenu. Et, bonne surprise, cette personne est francophone ! Découvrez le blog de Fevrier Dorian en cliquant sur ce lien !

Déjà, surpris de voir que je ne suis pas le seul à avoir galéré. Surpris aussi de voir qu’il a collecté un bon paquet de documentation dont il a retranscrit les liens dans son articles. C’est via ces derniers que j’ai découvert la façon d’utiliser LE widget qu’il me fallait. Car oui, en cherchant les widgets pour faire des listes déroulantes, je suis tombé sur un mystérieux « Combobox ». Seulement, aucun des codes fourni ne fonctionnait et pour cause, le module était introuvable. Vous allez comprendre pourquoi…

Le widget Combobox

Le widget Combobox est exactement celui qu’il me fallait. J’ai découvert au travers de mes recherches que c’est un nom assez commun donné aux widgets de la plupart des GUI, dont la définition, selon wikipédia, est :

Une combo box est un widget d’interface graphique utilisateur couramment utilisé. Traditionnellement, c’est une combinaison d’une liste déroulante (drop down menu) ou une liste d’élément avec une ligne modifiable (textbox), permettant à l’utilisateur d’écrire une valeur directement ou de la choisir parmi une liste d’options existante. Aujourd’hui, la distinction de base entre une combo box et une liste déroulante a le plus souvent disparue.

Source : http://en.wikipedia.org/wiki/Combo_box

On s’approche de plus en plus de mon but : avoir une liste déroulante simple, où on ne fait que choisir un élément dans la liste. Or, visiblement ici, on peut aussi éditer les éléments.  C’est alors que je vois sur la page Wikipédia :

Le terme « combo box » est parfois utilisé pour signifier « liste déroulante ». En Java et .NET, « combo box » n’est pas un synonyme de « liste déroulante ». La définition de « liste déroulante » est parfois clarifiée par les termes « combo box non éditable » (ou quelque chose de similaire) afin de la distinguer de la « combo box » originale.

Source : http://en.wikipedia.org/wiki/Combo_box

Peut-être (sûrement même…) que la combobox du Python possède un attribut permettant d’empêcher la modification de la liste des éléments. Il me faut donc de la documentation ! Et j’ai découvert un site listant l’utilisation d’une Combobox avec Tkinter (merci encore à Dorian) : http://www.tcl.tk/. Et avec la page qui m’intéresse : http://www.tcl.tk/man/tcl8.5/TkCmd/ttk_combobox.htm

Alors oui, ça n’est pas du python. Ce n’est même pas tkinter mais Tcl/Tk. Sachant que tkinter est une surcouche permet d’utiliser Tcl/Tk via le Python, ce n’est pas un souci 🙂 Les éléments affichés nous serons utiles, avec un petit peu de réflexion.

Implémentation du widget Combobox

Passons à la pratique, en se servant des nombreux liens de documentation à notre portée ! Commençons déjà par le nom de la combobox du site : « ttk::combobox« . Le « ttk:: » signifie que le widget combobox se situe dans la classe « ttk« . Ttk est défini dans la documentation de Python par « Tk themed widgets ». En gros, on va pouvoir appliquer une certaine apparence aux widgets de base. Dans la documentation, on nous conseille d’inclure ce module de la façon suivante :

De cette façon, les widgets de base importés par la première ligne seront modifiés par la classe ttk que l’on importe à la deuxième ligne. On garde une uniformité de l’apparence, et ça c’est plutôt cool ! 🙂

On va mettre ça dans un squelette de programme graphique utilisant tkinter :

On va ajouter le widget combobox maintenant. En regardant sur cette page, nous allons pouvoir déterminer quels arguments utiliser pour l’instanciation du widget. J’ai retenu ceux-ci :

  • textvariable : Doit être l’objet StringVar() spécifique à Tkinter. Cet objet contiendra l’élément sélectionné de la liste. Si nous modifions, via « variable.set(‘valeur‘)« , la valeur de l’objet, l’élément sélectionné de la liste changera également. Ca fonctionne également dans l’autre sens : si on sélectionne un élément de la liste, notre objet changera sa valeur. Ce n’est pas requis, mais dans certains cas ça peut être utile
  • values : Est une variable de type list ou tuple. Ce que contiendra cette variable sera le contenu de la liste de notre combobox.
  • state : c’est l’attribut le plus intéressant à mes yeux. Il permet de dire si on peut modifier la liste (normal) ou non (readonly), ou bien la désactiver totalement (disabled). Et readonly est le choix qui s’est porté à moi.

Ce qui donnera ceci, par exemple :

Et visuellement, ceci :

combobox4

Aller un peu plus loin

Parfait. Nous avons notre liste déroulante, que peut-on faire avec ? Voici quelques lignes de codes que j’ai utilisées et qui pourront peut-être vous être utile 🙂

Sélectionner le premier élément de la liste automatiquement

… Sinon, nous avons un vide correspond à une valeur nulle. Logique après, la première ligne du widget est censée être utilisée pour écrire nous-même une valeur. Mais nous sommes en readonly, donc pas de modification ! Pour afficher la première valeur de la liste, nous allons passer par self.fruitSelect (qui est une instance de StringVar()) et qui, pour rappel, possède la valeur sélectionnée de la liste. Cette dernière changera de valeur selon la valeur de notre objet StringVar() également.

Pour modifier la valeur de self.fruitSelect, nous utilisons la méthode set(str). Dans notre cas, nous allons fournir le premier élément de la liste des fruits dans self.stockFruits. Ce qui donne ceci :

Après exécution, nous constaterons que la liste déroulante aura directement pour valeur sélectionnée « Pomme » !

Exécuter une méthode après avoir cliqué sur un élément

Il y a une méthode intégrée aux combobox permettant d’exécuter une autre méthode en cliquant sur la combobox. C’est-à-dire avant de sélectionner un objet, donc en ouvrant simplement la liste. Ca s’appelle postcommand. Bien, s’ils se sont cassés la tête à faire ça, on peut logiquement se dire qu’ils ont fait pareil pour le cas où on sélectionne un objet de la liste… Bien évidemment, rien n’est simple dans la vie et ceci a été soit laissé de côté, soit oublié.

Ce n’est pourtant pas impossible et une astuce simple permet d’arriver à nos fins grâce à la méthode .bind() (elle est présente dans TOUS les widgets !) et à l’événement envoyé par la combobox : <ComboboxSelected>.

Petit code de test :

Petite astuce, les événements que .bind() va cibler sont entourés de < et >. Nous aurons donc un duplication de ces caractères 😉

Fin !

En espérant que ceci soit utile à quelqu’un d’autre que moi 🙂

Rappel des liens de ce billet :


Related Posts Plugin

Lyyn~

Lyyn~

L'informatique est un monde magique et complexe, partager quelques connaissances et astuces au travers de ce blog me permet de participer à la construction d'un web meilleur pour tous !

  • zbag

    Merci pour ces explications, ça m’a bien aidé. Je me fais un logiciel de carnet de vocabulaire thématique pour réviser mon anglais. Je voulais ajouter un menu déroulant pour sélectionner le thème de vocabulaire que je veux afficher.
    Grâce à tes explications ça marche nickel.

    • Merci à toi ! Heureux que mon guide ait servi 🙂

  • micronova

    merci, pour ces explications, je développe actuellement un système d’interface de jeu de rôle pour pouvoir masteriser des amis à distances, et disons que pour sélectionner une arme, c’est plus simple de la choisir parmis une liste que de devoir la taper (avec le risque de faire des fautes et tout) encore merci

    • Merci pour ton retour ! 🙂

  • claude

    Cet exemple ne marche pas si on remplae par exemple « poire » par « pêche »,
    Une suggestion?

    • Bonjour,

      Désolé du délai, il me semblait avoir déjà répondu. J’ai testé le remplacement du mot « poire » par « pêche » et n’ai pas rencontré le moindre souci. Qu’avez-vous comme erreur ?

  • Termon

    Merci beaucoup pour ce précieux sujet, on ne trouve que trop peu d’aides sur les Comboboxes sur Google comme tu l’as écrit 😉

    • Merci à toi pour le retour, ça me fait plaisir 🙂

  • RubMic

    Au top ! Je viens de tomber sur la même galère pour une simple liste. Tu m’as bien dépanné !
    J’vais continué à visiter ton site à la recherche de doc utiles 😀 .
    Sincères remerciements.

    • Merci pour ton retour 🙂

  • Kacem Mind

    Comment récupérer la valeur séléctionnée dans cette liste?
    Genre je séléctionne BANANE et je veux que Banane me soit retournée pour utiliser ce choix plus tard

  • Kacem Mind

    *****************Urgent!!!!!!!!!!!!!
    Comment récupérer la valeur séléctionnée dans cette liste?
    Genre je séléctionne BANANE et je veux que Banane me soit retournée pour utiliser ce choix plus tard

    Merci