2017-10-21 51 views
1

Je souhaite que l'utilisateur puisse entrer une valeur entière dans le widget Spinbox. Si la valeur entrée n'est pas un nombre entier ou est un nombre entier en dehors des limites de Spinbox, dès que Spinbox perd le focus, la valeur dans le contenu de Spinbox doit revenir à une valeur par défaut.Validation de widget dans tkinter

Dans l'exemple de code, j'utilise le widget Entrée juste pour que le Spinbox puisse perdre le focus.

Si l'utilisateur revient à Spinbox pour entrer une nouvelle valeur, son entrée n'est pas validée. Je confirme la remarque de Malcolm dans Interactively validating Entry widget content in tkinter que la fonctionnalité validatecommand=command est effacée dès que cette commande met à jour la valeur du widget.

Existe-t-il un moyen de valider la valeur entrée dans la Spinbox de manière répétée et pas seulement une fois?

from tkinter import * 


class GUI: 

    def __init__(self): 
     # root window of the whole program 
     self.root = Tk() 
     self.root.title('Validate Spinbox') 

     # registering validate and invalid commands 
     validate_cmd = (self.root.register(self.validate), '%P') 
     invalid_cmd = (self.root.register(self.invalid)) 

     # creating a Label 
     items_lbl = Label(self.root, text="# of items (5-10):") 
     items_lbl.grid(row=0, column=0) 

     # creating a Spinbox widget 
     self.items_var = StringVar() 
     self.items_var.set(7) 
     items_count = Spinbox(self.root, textvariable=self.items_var, 
           from_=5, to=10, width=4, validate='focusout', 
           validatecommand=validate_cmd, 
           invalidcommand=invalid_cmd) 
     items_count.grid(row=0, column=1) 

     # creating an Entry widget 
     self.entry_var = StringVar() 
     self.entry_var.set("Input some text here") 
     text_entry = Entry(self.root, textvariable=self.entry_var) 
     text_entry.grid(row=1, column=0) 

    def validate(self, entry): 
     try: 
      value = int(entry) 
      valid = value in range(5, 11) 
     except ValueError: 
      valid = False 
     if not valid: 
      self.root.bell() 
     return valid 

    def invalid(self): 
     self.items_var.set(7) 


if __name__ == '__main__': 
    main_window = GUI() 
    mainloop() 
+1

'validatecommand' reste OK, il est la' validate' paramètre lié à l'événement 'focusout' qui se réinitialiser – PRMoureu

+0

@PRMoureu: Merci pour votre réponse !!! Est-il possible de ne pas réinitialiser le paramètre ** validate **? Le plus préférablement: Comme je suis nouveau à Python, je serais grandement obligé si vous pouviez modifier mon code. – nkana

Répondre

1

Je trouve une grande explication ici (dans le dernier paragraphe du chapitre Validation):

http://stupidpythonideas.blogspot.fr/2013/12/tkinter-validation.html

Si votre validateCommand (ou invalidCommand) modifie directement ou indirectement l'entrée (par exemple en appelant set sur son StringVar), la validation sera désactivée dès que votre fonction retournera. (C'est ainsi que Tk empêche une boucle infinie de valider en déclenchant une autre validation.) Vous devez le réactiver (en appelant config). Mais vous ne pouvez pas le faire depuis l'intérieur de la fonction, car il est désactivé après le retour de votre fonction.

Mais vous devez appliquer quelques modifications pour pouvoir utiliser cette astuce.

Vous devez faire l'Spinbox un attribut d'instance, avec self:

self.items_count = Spinbox(self.root, textvariable=self.items_var, 
         from_=5, to=10, width=4, validate='focusout', 
         validatecommand=validate_cmd, 
         invalidcommand=invalid_cmd) 
self.items_count.grid(row=0, column=1) 

Et vous pouvez appeler self.items_count.after_idle(...) dans la méthode validate:

def validate(self, entry): 
    try: 
     value = int(entry) 
     valid = value in range(5, 11) 
    except ValueError: 
     valid = False 
    if not valid: 
     self.root.bell() 
     self.items_count.after_idle(lambda: self.items_count.config(validate='focusout')) 
    return valid 
+1

Merci beaucoup !!! Problème résolu!!!!!! – nkana

+0

Content d'aider, j'apprends aussi quelque chose grâce à l'auteur de ce blog – PRMoureu