IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Utiliser un objet à partir de son nom


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 206
    Par défaut Utiliser un objet à partir de son nom
    Bonjour à tous,

    Cherchant à créer un format "numérique" pour des Entry Tkinter, j'utilise "validate" afin de limiter la saisie (pas de problèmes !), mais je cherche également à modifier la valeur du widget selon certaines conditions, et c'est là que je bloque : en utilisant validatecommand, je n'arrive pas à entrer mon objet dans les paramètres, seulement son nom sous format string. Ceci semble normal du fait du "register", mais je souhaite donc pour "convertir" la string en objet.

    Auriez-vous une idée de comment m'y prendre ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    import tkinter as tk
     
    def NumValidate(keycode, MyEntry, valuetocheck):
     
        if keycode in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]:
            return True
     
        if keycode in [",", "."] and len(valuetocheck) == 0:
            MyEntry.insert(0, "0.")
            return False
     
        if keycode in [",", "."] and "." in valuetocheck[:-1]:
            return False
     
        if keycode in [".", ","]:
            MyEntry.delete(0, "end")
            MyEntry.insert(0, valuetocheck[:-1] + ".")
            return False
     
        return False
     
    root = tk.Tk()
     
    myEntry = tk.Entry(root, name='myEntry', width=40)
    myEntry.config(validate="key", validatecommand=(root.register(NumValidate), '%S', '%W', '%s'))
     
    myEntry.pack()
     
    root.mainloop()
    En vous remerciant par avance,

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 738
    Par défaut
    Salut,

    Citation Envoyé par wulfram Voir le message
    mais je souhaite donc pour "convertir" la string en objet.

    Auriez-vous une idée de comment m'y prendre ?
    Avec la méthode .nametowidget

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 206
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,



    Avec la méthode .nametowidget

    - W
    Bonsoir,

    Merci bien pour votre retour.

    L'inconvénient de cette méthode, est qu'elle nécessite de pouvoir passer le "root" sous forme d'objet, alors que je ne peux le récupérer que sous forme de String du fait du register.

    Je pensais avoir résolu le problème avec une classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    import tkinter as tk
     
    class NumHandle(tk.Entry):
        def __init__(self, master=None, **kwargs):
            super().__init__(master, **kwargs)
            cmd = (self.register(self.NumValidate), '%S', '%s')
            self.config(validate="key", validatecommand=cmd)
     
        def NumValidate(self, keycode, valuetocheck):
     
            if keycode in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]:
                return True
     
            if (keycode in [",", "."]) and (len(valuetocheck) == 0):
                self.delete(0, 'end')
                self.insert(0, "0.")
                return False
     
            if (keycode in [",", "."]) and ("." in valuetocheck):
                return False
     
            if keycode in [".", ","]:
                self.delete(0, "end")
                self.insert(0, valuetocheck + ".")
                return False
     
            return False
     
    root = tk.Tk()
     
    myEntry = NumHandle(root, width=40)
    myEntry.pack()
     
    root.mainloop()
    Néanmoins, dès que la méthode delete ou insert est appelée par la validation (donc quand je rentre un "." ou "," dans mon cas), il n'y a plus aucune vérifications qui s'applique, et il est donc possible de saisir tout ce que l'on veut, ce qui n'est pas pratique !

  4. #4
    Membre Expert Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Par défaut
    Je vois là pas mal de points douteux.

    [1] MyEntry arg et la visibilité de myEntry
    myEntry comme une instance de Entry est visible pour NumValidate. MyEntry passé par '%W' est par définition un 'String' étant le nom d'objet Entry. Soit. Mais myEntry est visible pour NumValidate et il suffit de l'appeller directement (voir plus bas).

    [2] valuetocheck mal-comprise ?
    L'arg valuetocheck passé par '%s' est par définition la valeur déjà entrée sur l'Entry avant de faire tapper le keycode, c'est-à-dire le keycode n'y est pas inclu. Par conséquence, plusieurs locations qui font appeller valuetocheck par valuetocheck[:-1] ne serait pas judicieuses. Il faut faire simplement s'écrire comme valuetocheck, c'est tout.

    [3] la méthode delete() et la nécessité de re-config l'Entry après
    Il me semble qu'une re-configuration serait nécessaire aux deux endroits qui font appeller la méthode delete() pour réétablir le comportement et de relier le callback à l'objet myEntry. Est-ce qu'il y a une autre façon de faire, j'en suis pas sûr, sans doute je n'y ai pas pensé trop.

    Voilà comment je modifierais le code pour qu'il au moins marche avec la fonctionnalité partielle écrite comme base pour une expansion futur sans doute latante compléter la fonctionnalité expérimentale dans l'idée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    def NumValidate(keycode, objname, valuetocheck):
     
        if keycode in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]:
            return True
     
        if (keycode in [",", "."]) and (len(valuetocheck)==0):    #pas == 1
            myEntry.delete(0, 'end')
            myEntry.insert(0, '0.')
            # re-config semble nécessaire
            myEntry.config(validate="key", validatecommand=(root.register(NumValidate), '%S', '%W', '%s'))  #re-register
            return False
     
        if (keycode in [",", "."]) and (len(valuetocheck)==1):
            return True
     
        if (keycode in [",", "."]) and ("." in valuetocheck):   #pas in valuetocheck[:-1]
            return False
     
        if keycode in [".", ","]:
            myEntry.delete(0, 'end')
            myEntry.insert(0, valuetocheck + '.')   #pas valuetocheck[:-1]
            # re-config semble nécessaire
            myEntry.config(validate="key", validatecommand=(root.register(NumValidate), '%S', '%W', '%s'))  #re-register
            return False
     
        return False
    et j'ai renommé MyEntry par un nom plus neutre pour ne pas confondre par trop ressemblance à myEntry.

    Voilà, pour le moment.

Discussions similaires

  1. [Free Pascal] Est-il possible de créer un objet à partir de son nom de classe ?
    Par TheFreeBerga dans le forum Free Pascal
    Réponses: 5
    Dernier message: 01/04/2017, 11h43
  2. Réponses: 3
    Dernier message: 14/04/2009, 18h09
  3. [IL]Instancier un objet à partir de son nom de classe
    Par neo.51 dans le forum Framework .NET
    Réponses: 2
    Dernier message: 08/08/2007, 11h43
  4. [VB.NET] Obtenir un objet à partir de son nom
    Par bart64 dans le forum Windows Forms
    Réponses: 3
    Dernier message: 31/12/2006, 12h37
  5. Réponses: 3
    Dernier message: 12/07/2006, 16h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo