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 :

tkinter fonction avec arguments


Sujet :

Python

  1. #1
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut tkinter fonction avec arguments
    Bonsoir,
    J'ai réalisé un programme qui effectue la recherche d'une chaine dans des fichiers (plus 2 ou 3 autres bricoles).
    Je bloque sur tkinter.
    En effet, ma fonction recherche ne tient pas compte des valeurs récupérées par les Entry, ...
    Mon programme ne déclenche pas d'erreur mais n'effectue la recherche qu'avec les valeurs que j'ai mis par défaut pour que cela tourne...
    Voici mon programme :
    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
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    import os, re
    import tkinter as tk
    from tkinter.scrolledtext import ScrolledText
    from tkinter import filedialog
     
    def choisir_dossier ():
        global rep
        "ouvre un dialogue de sélection de répertoire"
        rep = filedialog.askdirectory(
            title="Sélectionnez un répertoire",
            mustexist=True,
            parent=fenetre,
        )
        if rep:
            print(rep)
            remplir_liste(rep)
     
     
    def remplir_liste (dossier):
        cvar_fichiers.set(os.listdir(dossier))
     
    def afficher_fichier (event):
        os.path.join(rep,liste_fichiers.get(liste_fichiers.curselection()))
     
     
    # récupérer un élément cliqué dans une Listbox
    def clic(evt):
        global ext
        widget = evt.widget
        i=widget.curselection()  ## Récupération de l'index de l'élément sélectionné
        ext = l_box.get(i)  ## On retourne l'élément (un string) sélectionné
     
    # init variables globales
     
    rep = "/"
    mot = "acide"
    ext=".tex"
     
    def recherche(chaine="acide", path='/', extension=".tex"):
        affichage_texte.delete("1.0", tk.END)
        """recherche un mot dans le contenu des fichiers"""
        cpt = 0
        for root, directories, files in os.walk(path):  
            for file in files:
                if file.endswith(extension) and file.endswith(extension) != '.pdf':
                    try:
                        f = open(os.path.join(root,file), 'r',encoding='utf-8').read()
                        if chaine.lower() in f.lower():
                            # on insère le nouveau contenu texte du fichier
                            affichage_texte.insert("1.0", os.path.join(root,file)+"\n")
                            cpt = cpt + 1
                    except UnicodeDecodeError:
                        try:
                            f = open(os.path.join(root,file), 'r',encoding='latin-1').read()
                            if chaine.lower() in f.lower():
                                # on insère le nouveau contenu texte du fichier
                                affichage_texte.insert("1.0", os.path.join(root,file)+"\n")
                                cpt = cpt + 1
                        except UnicodeDecodeError:
                            # on insère le nouveau contenu texte du fichier
                            affichage_texte.insert("Pb d'encodage : ", os.path.join(root,file)+"\n")
                            pass
     
     
     
     
    regex = re.compile(mot)
     
    # fenêtre principale
    fenetre = tk.Tk()
    fenetre.title("Recherche d'un mot")
    conteneur_fichiers = tk.Frame(fenetre)
    # conteneur redimensionnable
    conteneur_fichiers.columnconfigure(0, weight=1)
    conteneur_fichiers.rowconfigure(1, weight=1)
    # étiquette texte dans ce conteneur
    tk.Label(
        conteneur_fichiers,
        text="--------------------------------"
    ).grid(row=0, column=0, sticky=tk.EW)
    # liste des fichiers
    cvar_fichiers = tk.StringVar()
    liste_fichiers = tk.Listbox(conteneur_fichiers, listvariable=cvar_fichiers)
    liste_fichiers.grid(row=1, column=0, sticky=tk.NS+tk.EW)
    # avec sa scrollbar
    vbar_fichiers = tk.Scrollbar(conteneur_fichiers, orient=tk.VERTICAL)
    vbar_fichiers.grid(row=1, column=1, sticky=tk.NS+tk.W)
    # connection de la scrollbar à la liste des fichiers
    liste_fichiers.configure(yscrollcommand=vbar_fichiers.set)
    vbar_fichiers.configure(command=liste_fichiers.yview)
    # affichage des dossiers sur simple clic
    # sur un dossier de la liste
    liste_fichiers.bind("<ButtonRelease-1>", afficher_fichier)
    # bouton de type 'Parcourir'
    tk.Button(
        conteneur_fichiers,
        text="Sélectionner un dossier",
        command=choisir_dossier,
    ).grid(row=2, column=0)
    # on place le conteneur dans la fenêtre principale
    # avec des marges padx et pady
    conteneur_fichiers.grid(row=0, column=0, sticky=tk.NS+tk.EW, padx=5, pady=5)
    # on crée un conteneur pour l'affichage
    conteneur_affichage = tk.Frame(fenetre)
    # on rend le conteneur redimensionnable
    conteneur_affichage.columnconfigure(0, weight=1)
    conteneur_affichage.rowconfigure(1, weight=1)
    # on crée une étiquette texte dans ce conteneur
    tk.Label(
        conteneur_affichage,
        text="Présent ici : "
    ).grid(row=0, column=0, sticky=tk.EW)
     
    # listbox extension
    l_box = tk.Listbox(fenetre)
    l_box.grid(row=2,column=0,sticky=tk.E)
    l_box.bind('<ButtonRelease-1>',clic)  # on associe l'évènement "relachement du bouton gauche la souris" à la listbox
    liste_ext = [".csv", ".doc", ".docx", ".py", ".tex", ".txt", ".xls", ".xlsx" ,".*"]
    for name in liste_ext:
        l_box.insert('end', name)
    # fenetre saisie mot
    value = tk.StringVar(fenetre)
    value.set("recherche")
    entree = tk.Entry(fenetre, textvariable=value, width=30)
    entree.grid(row=0,column=3,sticky=tk.E)
    mot=entree.get()
    # on crée la zone d'affichage de texte
    affichage_texte = ScrolledText(
        conteneur_affichage,
        bg="white",
        fg="blue",
        font="sans 12 bold",
        height=10,
        width=20,
    )
    affichage_texte.grid(row=1, column=0, sticky=tk.NS+tk.EW)
     
     
    # on ajoute un bouton 'recherche_mot'
    tk.Button(
        conteneur_affichage,
        text="Recherche mot dans le contenu",
        command=lambda: recherche(mot,rep,ext)
    ).grid(row=2, column=6, sticky=tk.E)
    # on ajoute un bouton 'quitter'
    tk.Button(
        conteneur_affichage,
        text="Quitter",
        command=fenetre.destroy
    ).grid(row=6, column=6, sticky=tk.E)
    # on place le conteneur dans la fenêtre principale
    # avec des marges padx et pady
    conteneur_affichage.grid(row=0, column=1, sticky=tk.NS+tk.EW, padx=5, pady=5)
    # on rend la fenêtre redimensionnable
    fenetre.rowconfigure(0, weight=1)
    fenetre.columnconfigure(1, weight=1)
     
     
    remplir_liste("./")
    print(rep,ext,mot)
    # pour finir
    # on lance la boucle événementielle principale
    fenetre.mainloop()

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

    On part d'un petit programme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    import tkinter as tk
     
    entry = tk.Entry()
    entry.pack()
    tk.Button(text='go', command = lambda: print(entry.get())).pack()
    tk.mainloop()
    qui essaie d'afficher sur la console ce qui a été récupéré dans l'entry lorsqu'on a appuyé sur "Go". Et on peut constater que çà fonctionne (comme décrit dans la documentation d'ailleurs).

    Une fois qu'on est un peu confiant sur le "bon" fonctionnement de la mécanique de base, on essaie de comprendre ce qui ne va pas dans le code.

    On peut supposée que c'est la fonction recherche qui n'est pas appelée avec les paramètres attendus. Donc on cherche où elle est appelée... On a de la chance, ce n'est appelé que ligne 143 lorsqu'on appuie sur un Button.

    Puis on regarde avec quels paramètres c'est appelé, tiens le premier est "mot". Il y en a plein mais le dernier est ligne 126
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    value.set("recherche")
    entree = tk.Entry(fenetre, textvariable=value, width=30)
    entree.grid(row=0,column=3,sticky=tk.E)
    mot=entree.get()  # ligne 126
    quand aux autres, ils se foutent du contenu de l'Entry donc on peut les ignorer.

    Puis on peut conclure que entree.get() étant une chaine caractère donc quelque chose de non mutable, si on ne met pas à jour plus tard cette variable (à défaut d'appeler recheche avec le contenu actualisé de l'Entry plutôt qu'avec un vieux cadavre)... ben, c'est cohérent avec le problème constaté.
    ma fonction recherche ne tient pas compte des valeurs récupérées par les Entry, ...
    Faut-il aussi vous expliquer comment écrire la ligne 143 pour que?

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

  3. #3
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut
    Merci wiztricks.
    J'ai exploré des pistes pendant plus d'une heure, sans succès.
    Je veux bien effectivement une explication pour la ligne 143 : je crois que pour tkinter, je suis intellectuellement déficient.

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

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Salut,

    Citation Envoyé par marco056 Voir le message
    J'ai exploré des pistes pendant plus d'une heure, sans succès.
    Je veux bien effectivement une explication pour la ligne 143 : je crois que pour tkinter, je suis intellectuellement déficient.
    A cette ligne tu as ceci : command=lambda: recherche(mot,rep,ext) donc à chaque clique sur le bouton "Recherche mot dans le contenu" la fonction recherche est exécutée et le mot à rechercher est passé via le paramètre mot mais cette variable mot a été initialisée à la ligne 36 : mot = "acide" puis à la ligne 126 : mot=entree.get() ensuite elle ne change plus, elle contient toujours la chaine "recherche" (car c'est cette chaine que contient le champs texte (entree) au moment où la ligne 126 est exécutée).

    Et c'est ce qui explique ton problème...

    En fait tu as "crée" la variable tkinter "value" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    # fenetre saisie mot
    value = tk.StringVar(fenetre)
    value.set("recherche")
    entree = tk.Entry(fenetre, textvariable=value, width=30)
    Et tu l'associes ensuite au champs texte entree (textvariable=value) c'est donc cette variable et non la variable "mot" qui est actualisée chaque fois que le contenu du champs texte (entree) change. Du coup c'est le contenu de cette variable qu'il aurait fallu passer en argument à la place de la variable "mot" : command=lambda: recherche(value.get(),rep,ext)...

    Mais en fait tu pourrais te passer de la variable tkinter "value" (et même de la variable "mot" d'ailleurs) et passer en argument à la place de la variable "mot" ceci : entree.get(), c'est-à-dire tu remplaces la ligne 143 par ceci : command=lambda: recherche(entree.get(),rep,ext)...

  5. #5
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut
    Ok, merci.
    J'avais mis effectivement 2 fois mot car sans celui-ci initialisé, j'avais un message d'erreur à un moment donné.
    Pour le reste, c'est sympa de m'avoir débloqué. Je vais essayer de digérer cela.
    Comme j'ai ce programme à compléter avec d'autres fonctions, je vais peut-retomber sur des os...
    Merci encore et bonne semaine à tous et toutes.

Discussions similaires

  1. fonction avec arguments après command= dans tkinter
    Par dg1312 dans le forum Général Python
    Réponses: 9
    Dernier message: 27/05/2013, 21h22
  2. fonction avec argument predefini
    Par duplo dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 29/08/2006, 19h06
  3. onChange et fonction avec arguments
    Par pierre.egaud dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 13/06/2006, 11h02
  4. DLL export de fonction avec argument
    Par slate dans le forum C
    Réponses: 3
    Dernier message: 31/05/2006, 10h36
  5. creer une fonction avec arguments
    Par niglo dans le forum ASP
    Réponses: 3
    Dernier message: 03/06/2005, 08h04

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