Outils pour utilisateurs

Outils du site


valid_car_entry

Comment maitriser l'édition caractère par caractère dans un widget "Entry"

Objectif

Dans certains cas de saisie de données, il vaut mieux vérifier chaque caractère pour l'empêcher ou pour le modifier, que d'attendre la sortie du widget (perte de focus) ou même la fin d'une saisie complète pour découvrir qu'il y a des caractères interdits ou inadaptés dans une valeur. Par exemple, on peut vouloir empêcher la lettre “O” dans un code postal, ou convertir les caractères accentués en non-accentués.

Principe

On utilise des options du widget Entry (validate et validatecommand) qui, curieusement, ne sont pas dans le manuel Tkinter de Mexico (2008). Par contre, ils se trouvent ici: http://effbot.org/tkinterbook/entry.htm.

Comment empêcher certains caractères

Dans l'exemple ci-dessous, on veut limiter la saisie à soit un chiffre (de 0 à 9), soit la touche backspace.

la ligne:

self.saisie.bind("<Key>", self.quelletouche)

fera que chaque touche clavier va générer un évènement qui lancera la méthode “quelletouche()”. Celle-ci ne fera qu'une seule chose: elle stockera la valeur de l'évènement.

La ligne:

self.saisie.configure(validate="key",validatecommand=self.veriftouche)

fera que seules les touches qui rendent la méthode veriftouche() vraie (=True) seront insérées dans le widget Entry. Dans le cas contraire, rien ne sera inséré.

Rien n'empêche, dans la méthode de validation, de renvoyer un message d'alerte comme un “bip” lorsque la touche qui vient d'être saisie n'est pas dans la liste acceptable:

    def veriftouche(self):
        if (self.touche.char in "0123456789") or (self.touche.keysym == "BackSpace"):
            return True
        else:
            self.bell()
            return False

Dernier point, en cas d'insertion, il vaut mieux que celle-ci respecte le protocole de validation plutôt que d'utiliser la méthode habituelle “.insert(). On le fait ici en utilisant .event_generate(car) qui envoie tout simplement le caractère comme s'il venait du clavier. Pour bien montrer que cette insertion passe par la validation, j'ai mis “toto” au milieu de la chaîne à insérer.

Code

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
import Tkinter
 
class Application(Tkinter.Frame):
 
    def __init__(self, master=None):
        Tkinter.Frame.__init__(self, master, background="ivory")
 
        self.grid()
        self.saisie=Tkinter.Entry(self, background="white", width=50)
        self.saisie.configure(validate="key",validatecommand=self.veriftouche)
        self.saisie.bind("<Key>", self.quelletouche)
        self .saisie.grid(row=0, column=0, sticky="EW")
 
        self.bout=Tkinter.Button(self, text="insert", command=lambda x="123toto789": self.insevent(x))
        self.bout.grid(row=1)
 
        self.saisie.focus_set()
        self.touche=None
 
    def quelletouche(self, event):
        self.touche=event
 
    def veriftouche(self):
        return (self.touche.char in "0123456789") or (self.touche.keysym == "BackSpace")
 
    def insevent(self, ch):
        for car in ch:
            self.saisie.event_generate(car)
 
fen=Tkinter.Tk()
app=Application(fen)
fen.mainloop()

Comment convertir certains caractères au fur et à mesure qu'ils sont tapés

On utilise la même technique que précédemment.

#!/usr/bin/python
# -*- coding:utf-8 -*-
 
from __future__ import division
 
import Tkinter
 
##################################################################
class Application(Tkinter.Frame):
 
    def __init__(self, master=None):
 
        Tkinter.Frame.__init__(self, master)
 
        self.grid()
        self.varsaisie = Tkinter.StringVar()
        self.varsaisie.set("")
        self.saisie=Tkinter.Entry(self,  background="white", width=50, textvariable=self.varsaisie)
 
        self.saisie.bind("<Key>", self.quelletouche)
 
        self.saisie.grid(row=0,column=0,padx=3, pady=6)
        self.saisie.focus_set()
 
        self.alpha1 = u"àÀâÂçÇéÉèÈêÊëËîÎïÏôÔùÙûÛüÜÿŸ"
        self.alpha2 = u"aAaAcCeEeEeEeEiIiIoOuUuUuUyY"
 
    def quelletouche(self, event):
        self.touche=event
        self.saisie.configure(validate="key",validatecommand=self.veriftouche)
 
    def veriftouche(self):
        i = self.alpha1.find(self.touche.char)
        if i>=0:
            self.saisie.event_generate(self.alpha2[i])
            return False
        else:
            return True
 
##############################################################################
# lancement et affichage au centre de l'écran de l'application
#
if __name__ == "__main__":
    fen=Tkinter.Tk()
    fen.title(u"Saisie controlée")
    app=Application(fen)
    fen.mainloop()


Amusez-vous bien!

valid_car_entry.txt · Dernière modification: 2009/10/17 17:11 par tyrtamos

Outils de la page