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 :

Appel de fonction dans une définition Tkinter ?


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 24
    Par défaut Appel de fonction dans une définition Tkinter ?
    Bonjour,

    J'ai une fonction qui est appelée sans mon consentement !

    Ce programme ouvre un fichier CSV ("produits.txt"), lit son contenu et l'enregistre dans une liste (produits). L'utilisateur peut actuellement ajouter des produits à cette liste, et enregistrer le nouveau contenu de la liste au fichier CSV.

    Or cette fonction "enregistrer" définie ligne 23 est appelée dès le lancement du programme, comme on peut le voir dans la console avec les "debug x" qui s'affichent. De ce que je comprend, c'est la ligne 115 qui pose problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    menu_fichier.add_command(label='Enregistrer', command=enregistrer("produits.txt", produits))
    Si j'enlève l'option 'command' je n'ai pas de soucis, la fonction n'est pas appelée. Et ce qui me gêne d'autant plus c'est que la fonction n'est pas appelée quand je clique sur 'Enregistrer' dans le menu 'Fichier'. Tout fonctionnait bien tout à l'heure, j'ai fait un peu de ménage dans le code et maintenant je sèche totalement.

    Est-ce que add_command() peut appeler une fonction de lui même ? Je ne sais pas comment chercher sur ce sujet. Merci pour votre aide.

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    # -*- coding:utf-8 -*-
     
    from tkinter import *
    from lib1 import *
    import csv
    import codecs
     
    produits = []
     
    # Récupération de la liste des produits
     
    def loadCSV(fname, liste):
        file = codecs.open(fname, "r", "utf-8")
     
        try:
            reader = csv.reader(file, delimiter=';')
            for row in reader:
                liste.append(row)
        finally:
            file.close()
        return liste
     
    # Enregistrement des ajouts d'une liste dans un fichier
     
    def enregistrer(fname, liste):
        print("debug1")
        l = 0
        file = codecs.open(fname, "r", "utf-8")
     
        try:
            print("debug2")
            reader = csv.reader(file, delimiter=';')
            for row in reader:
                print("debug l:"+str(l))
                l += 1
            new = liste[l:len(liste)]
        finally:
            file.close()
     
        file = codecs.open(fname, "a", "utf-8")
        writer = csv.writer(file, delimiter=';' )
        for row in new:
            writer.writerow(row)
     
    # Ajout d'un produit
    def ajoutProduit():
        w_ajout_produit = Toplevel(w_root)
     
        def fermer():
            n = nom.get()
            r = reference.get()
            f = fournisseur.get()
     
            produits.append([n, r, f])
            w_ajout_produit.destroy()
     
            print("debug : longueur de produits = " + str(len(produits)))
     
        nom = StringVar()
        reference = StringVar()
        fournisseur = StringVar()
     
        lb_nom = Label(w_ajout_produit, text="Nom : ").grid(row=0, column=0, padx=5, pady=5, sticky=W)
        lb_reference = Label(w_ajout_produit, text="Référence : ").grid(row=1, column=0, padx=5, pady=5, sticky=W)
        lb_fournisseur = Label(w_ajout_produit, text="Fournisseur : ").grid(row=2, column=0, padx=5, pady=5, sticky=W)
        e_nom = Entry(w_ajout_produit, textvariable=nom).grid(row=0, column=1, padx=5, pady=5, sticky=E)
        e_reference = Entry(w_ajout_produit, textvariable=reference).grid(row=1, column=1, padx=5, pady=5, sticky=E)
        e_fournisseur = Entry(w_ajout_produit, textvariable=fournisseur).grid(row=2, column=1, padx=5, pady=5, sticky=E)
     
        btn_ajout = Button(w_ajout_produit, text="Ajouter le produit", command=fermer)
        btn_ajout.grid(row=3, column=0, columnspan=2, padx=5, pady=5)
     
    loadCSV("produits.txt", produits)
     
    ######################################
    # Affichage de la fenêtre principale #
    ######################################
     
    w_root = Tk()
     
    # Barre des menus
    menubar = Menu(w_root)
     
    # Fichier
    menu_fichier = Menu(menubar, tearoff=0)
    menubar.add_cascade(label='Fichier', menu=menu_fichier)
     
    # Fichier -> Nouveau
    menu_nouveau = Menu(menu_fichier, tearoff=0)
    menu_fichier.add_cascade(label='Nouveau', menu=menu_nouveau)
     
    # Fichier -> Nouveau -> Sous-menus
    menu_nouveau.add_command(label='Produit', command=ajoutProduit)
    #menu_nouveau.add_command(label='Recette', command=ajoutRecette)
    #menu_nouveau.add_command(label='Préparation', command=ajoutPreparation)
    #menu_nouveau.add_command(label='Application', command=ajoutApplication)
    #menu_nouveau.add_command(label='Mesure CIE L*a*b*', command=ajoutMesure_CIE)
    #menu_nouveau.add_command(label='Mesure spectrale', command=ajoutMesure_Spectrale)
     
    # Fichier -> Ouvrir
    #menu_ouvrir = Menu(menu_fichier, tearoff=0)
    #menu_fichier.add_cascade(label='Ouvrir', menu=menu_ouvrir)
     
    # Fichier -> Ouvrir -> Sous-menus
    #menu_ouvrir.add_command(label='Produit', command=ouvrirProduit)
    #menu_ouvrir.add_command(label='Recette', command=ouvrirRecette)
    #menu_ouvrir.add_command(label='Préparation', command=ouvrirPreparation)
    #menu_ouvrir.add_command(label='Application', command=ouvrirApplication)
    #menu_ouvrir.add_command(label='Mesure CIE', command=ouvrirMesure_CIE)
    #menu_ouvrir.add_command(label='Mesure spectrale', command=ouvrirMesure_Spectrale)
     
     
    # Fichier -> Enregistrer
    menu_enregistrer = Menu(menu_fichier, tearoff=0)
    menu_fichier.add_command(label='Enregistrer', command=enregistrer("produits.txt", produits))
     
    h = 640
    w = 480
    fps = 16
    w_root.config(menu=menubar)
    w_root.geometry("640x480")
    w_root.title('Utilitaire colorimétrique')
     
    def update():
        h=w_root.winfo_height()
        w=w_root.winfo_width()
        l_titre.grid()
        f_center.grid(padx=(w/2)-(f_center.winfo_width()/2), pady=(h/2)-(f_center.winfo_height()/2))
        w_root.after(fps, update)
     
    f_center = Frame(w_root)
    l_titre = Label(f_center, text="Utilitaire Colorimétrie")
    #placer le label dans la frame
    l_titre.grid()
    #placer la frame en la centrant
    f_center.grid(padx=w/2, pady=h/2)
     
    w_root.after(fps, update)
    w_root.mainloop()

  2. #2
    Membre averti
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 24
    Par défaut
    Réponse trouvée juste après avoir ouvert ce topic...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    menu_fichier.add_command(label='Enregistrer', command=lambda: enregistrer("produits.txt", produits))
    Pour une raison que j'ignore, il faut utiliser un lambda. Sinon la fonction 'enregistrer' et bel et bien appelée.

    Je laisse ce topic ouvert pour de futurs galériens comme moi, si un modo passe ici il peut le supprimer si besoin.

  3. #3
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    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 741
    Par défaut
    Salut,

    Citation Envoyé par Drolls Voir le message
    Pour une raison que j'ignore, il faut utiliser un lambda. Sinon la fonction 'enregistrer' et bel et bien appelée.
    enregistrer("produits.txt", produits) exécute la fonction.
    lambda fabrique une fonction anonyme qui exécutera enregistrer avec "produits.txt" et produits comme arguments.

    Prendre une fonction et l'associer à des objets, c'est comme si on fabriquait une méthode... et une sorte de premier pas vers la POO.

    Dans votre cas, produits est variable globale et "produits.txt" une constante, inutile de passer des paramètres à enregistrer.

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

  4. #4
    Membre averti
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 24
    Par défaut
    Merci pour la réponse.

    Pour la suite je vais avoir plusieurs fichiers csv, avec leur liste associée. J'ai d'abord fait une fonction "enregistrer" pour chaque fichier car ils n'ont pas tous le même format, puis j'ai voulu faire une fonction unique prenant en paramètres le nom du fichier, la liste à utiliser, le type de données, etc...

    De ce que je comprend et me souviens des cours que j'ai eu, l'utilisation d'un lambda permet de créer des fonctions spécialisées à partir de fonctions plus généralistes. Même si produits est une variable globale et "produits.txt" une constante, si je veux enregistrer recettes dans "recettes.txt", je peux soit passer par un lambda, soit par une fonction enregistrerRecettes. La seconde solution devient lourde si j'ai une dizaine de fichiers différents.

    Merci pour les explications.

    Manu

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    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 741
    Par défaut
    Salut,

    Citation Envoyé par Drolls Voir le message
    La seconde solution devient lourde si j'ai une dizaine de fichiers différents.
    Si vous avez une dizaine de fichiers différents et des traitements spécifiques, la solution générale sera de créer une classe.

    Maintenant, si vous avez des dizaines de fichiers différents mais qu'à l'instant T, un seul sera traité par le programme, on peut le faire avec des variables globales.

    Citation Envoyé par Drolls Voir le message
    J'ai d'abord fait une fonction "enregistrer" pour chaque fichier car ils n'ont pas tous le même format, puis j'ai voulu faire une fonction unique prenant en paramètres le nom du fichier, la liste à utiliser, le type de données, etc...
    car de toutes façons, vous allez avoir un tas de conditions à évaluer dans la fonction en suivant le format, le type des données, .... Et que cette évaluation soit fonction de variable globales ou de celles récupérées en paramètres (des variables locales), n'y change pas grand chose.

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 08/12/2006, 02h18
  2. Appel de fonction dans une action
    Par ogiacomo dans le forum Ada
    Réponses: 2
    Dernier message: 28/11/2006, 14h16
  3. Appel de fonction dans une classe
    Par saint-pere dans le forum Langage
    Réponses: 3
    Dernier message: 08/05/2006, 22h13
  4. Appel de fonction dans une page JSP
    Par Addouna dans le forum Servlets/JSP
    Réponses: 6
    Dernier message: 09/03/2006, 12h56
  5. Appel de fonction dans une classe
    Par Seth77 dans le forum Langage
    Réponses: 8
    Dernier message: 16/01/2006, 10h32

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