Partage
  • Partager sur Facebook
  • Partager sur Twitter

Tkinder : récupérer la valeur saisie

Sujet résolu
    18 novembre 2019 à 21:31:05

    Bonsoir,
    Je suis en train de faire un projet en Tkinder.
    Le cheminement :
    1/J'ai défini 3 zones de saisie 
    2/ Je demande à l'utilisateur de définir le montant (je mets une valeur par défaut mais l'utilisateur peut la changer).
    3/ Puis, je calcule un résultat avec ces 3 valeurs.
    Jusqu'à présent, je donnais un nom différent par variable.
    Avantages : très facile pour moi de récupérer les valeurs des variables définies par l'utilisateur 
    Inconvénients  : beaucoup de lignes.
    Du coup, j'ai essayé de simplifier mon code en utilisant un loop.
    Avantage : écrire une seule fois mon code et l'updater pour les différentes variables.

    Le problème : mon get récupère toujours la valeur que j'ai mis par défaut (ce qui est logique car dans mon code, au moment d'appuyer sur "calcul", je ne retourne pas vérifier le montant de mes variables (si les utilisateurs les a modifié). Car, en effet, je ne sais pas le faire étant donné que toutes mes variables ont le même nom à savoir "self.input_texte" (je ne sais donc pas différencier le nom de mes 3 variables).
    Voici mon code :
    (désolée par avance, si mon code est bancal, je fais de mon mieux, mais je n'ai pas encore beaucoup d'expériences en Python, notamment sur les classes)
    import tkinter as tk
    
    class Application_endettement(tk.Tk):
        def __init__(self):
            tk.Tk.__init__(self)
            self.data_endettement()
            self.bouton()
    
        def data_endettement(self):
            self.cadre = tk.Frame(self,borderwidth=3,relief="groove")
            self.cadre.grid(row=2,column=0,sticky="NSW",padx=3,pady=3,ipadx=45)
    
            self.test_dico={"Salaire mensuel": 767,"Loyer mensuel hors charges":595,"Pret mensuel hors charges :":469}
            i=0 
            self.value_for_computation={}
            for type, montant in self.test_dico.items():
                self.input_txt=tk.Label(self.cadre, text=type)
                self.input_txt.grid(row=(5+i),column=0,sticky="E")
                self.input_texte = tk.StringVar()
                self.input_texte.set(montant)
                self.ligne_input = tk.Entry(self.cadre, textvariable=self.input_texte, width=10,justify="center")
                self.ligne_input.grid(row=(5+i),column=1)
                self.input=float(self.input_texte.get())
                self.value_for_computation[type] = self.input
                i+=1
           
        def calcul(self):
            #mon calcul    
            self.endettement_non_compensation=round(self.value_for_computation["Pret mensuel hors charges :"]/(self.value_for_computation["Salaire mensuel"]+self.value_for_computation["Loyer mensuel hors charges"]*0.7)*100,2)
            
            #les résultats
            self.resultat = tk.StringVar()
            self.resultat.set("Endettement (méthode de non compensation) : {montant} %".format(montant=self.endettement_non_compensation))
            self.sortie = tk.Label(self.cadre, textvariable = self.resultat)
            self.sortie.grid(row=9,column=0,columnspan=2)
    
        def bouton(self):
            self.bouton = tk.Button(self.cadre, text = "Calculer", command = self.calcul)
            self.bouton.grid(row=8,column=0,columnspan=2)
    
    if __name__ == "__main__":
        app = Application_endettement()
        app.title("Calculatrice immobilier")
        app.minsize(500,500)
        app.mainloop() 

    Pouvez vous svp me donner des conseils?
    N'hésitez pas si vous avez besoin d'autres précisions!

    Merci pour votre aide :)
    Mathilde
    • Partager sur Facebook
    • Partager sur Twitter
      18 novembre 2019 à 23:45:02

      Le problème est que quand tu mets à jour tes entrées dans l'UI, ton code ne remet pas à jour le dictionnaire value_for_computation lignes 15-25 qui sert à faire tes calculs à la ligne 29. Ce qu'il faudrait ce que les valeurs des clés de ce dictionnaire  pointent dès le départ vers les chaînes dynamiques (les stringvar, intvar, etc) qui enregistrent les mises à jour. Voilà ce que ça donnerait sur la base de ton code (j'ai simplifié ton calcul en faisant juste une somme) :

      import tkinter as tk
       
      class Application_endettement(tk.Tk):
          def __init__(self):
              tk.Tk.__init__(self)
              self.data_endettement()
              self.bouton()
       
          def data_endettement(self):
              self.cadre = tk.Frame(self,borderwidth=3,relief="groove")
              self.cadre.grid(row=2,column=0,sticky="NSW",padx=3,pady=3,ipadx=45)
       
              self.test_dico={"a": 10,"b":20,"c":100}
              i=0
              self.value_for_computation={}
              for type, montant in self.test_dico.items():
                  self.input_txt=tk.Label(self.cadre, text=type)
                  self.input_txt.grid(row=(5+i),column=0,sticky="E")
                  self.input_texte = tk.StringVar()
                  self.input_texte.set(montant)
                  self.ligne_input = tk.Entry(self.cadre, textvariable=self.input_texte, width=10,justify="center")
                  self.ligne_input.grid(row=(5+i),column=1)
                  self.input=float(self.input_texte.get())
                  self.value_for_computation[type] = self.input_texte
                  i+=1
              
          def calcul(self):
              #mon calcul   
              a=self.value_for_computation["a"]
              b=self.value_for_computation["b"]
              c=self.value_for_computation["c"]
                 
              self.endettement_non_compensation=float(a.get())+float(b.get())+float(c.get())
               
              #les résultats
              self.resultat = tk.StringVar()
              self.resultat.set("Somme : {montant} ".format(montant=self.endettement_non_compensation))
              self.sortie = tk.Label(self.cadre, textvariable = self.resultat)
              self.sortie.grid(row=9,column=0,columnspan=2)
       
          def bouton(self):
              self.bouton = tk.Button(self.cadre, text = "Calculer", command = self.calcul)
              self.bouton.grid(row=8,column=0,columnspan=2)
       
      if __name__ == "__main__":
          app = Application_endettement()
          app.title("Calculatrice immobilier")
          app.minsize(500,500)
          app.mainloop()



      En réalité, on peut faire un code plus simple sans utiliser des chaînes dynamiques. Ça voudrait la peine des les utiliser si tu faisais qqchose de vraiment dynamique c'est à dire que par exemple ta somme se mette à jour automatiquement sans cliquer sur le bouton.

      • Partager sur Facebook
      • Partager sur Twitter
        19 novembre 2019 à 8:35:36

        Hello PascalOrtiz,

        Un grand merci pour ton aide ! Quel plaisir qu'à mon réveil, j'ai eu une solution et que je vais pouvoir avancer :).

        En effet, ca marche parfaitement bien maintenant.

        Je viens de voir en bas de ton post que tu as fait de la doc Tkinder. Je vais l'utiliser ! 

        Qu'est ce que ca signifie "sans utiliser des chaines dynamiques"? Est ce que tu peux me re-préciser stp ce qu'est une chaine dynamique ? :)

        En effet, je souhaite faire le code le plus simple possible.

        Merci encore PascalOrtiz

        Bonne journée,

        Mathilde

        • Partager sur Facebook
        • Partager sur Twitter
          19 novembre 2019 à 13:32:09

          Ce que j'appelle chaîne dynamique c'est StringVar que tu utilises dans ton code. Ça s'appelle souvent variables de contrôle.

          Dans de beaucoup de codes, on observe une sur-utilisation de ces variables Tkinter. Dans de nombreuses situations statiques, elles ne sont pas utiles, comme le confirme Bryan Oakley sur StackOverflow. Elle ne servent vraiment que lorsque des objets variables définis par des événements non contrôlables sont partagées dynamiquement par plusieurs widgets. Voici un exemple typique :

          Elles sont parfois utiles aussi pour mettre à jour automatiquement un grand nombre d’objets. Certains widgets, pour être convenablement contrôlés, doivent absolument utiliser une variable de contrôle, typiquement le widget bouton-radio ou le widget case à cocher.

          • Partager sur Facebook
          • Partager sur Twitter
            20 novembre 2019 à 10:15:23

            Bonjour Pascal,

            Excellent, merci pour cette précision, je vais voir pour les enlever.
            Merci pour ton partage !

            Mathilde

            • Partager sur Facebook
            • Partager sur Twitter

            Tkinder : récupérer la valeur saisie

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown