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 :

bouton.config() écrase les données de tous les boutons avec Tkinter


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 299
    Par défaut bouton.config() écrase les données de tous les boutons avec Tkinter
    Bonjour,
    J'ai un problème avec mes boutons. Je les récupère depuis un fichier de sauvegarde 'saver:txt' grace auquel je peux creer ensuite les boutons avec pack. Je mets dans chaque bouton une commande pour ouvrir une fenêtres avec les détails du fichier et la possibilité de le supprimer. Donc pour cela je passe en argument le chemin du fichier (pour les infos) et le bouton lui-meme (pour l'enlever quand le fichier est supprimé). Les boutons un par un sont bien générés (ligne 122) mais j'ai l'impression que le bouton suivant écrase les données du précédent. En effet quand on a ''open'' deux fichiers puis qu'on ferme et réouvre le programme et que finalement on clique sur le premier bouton, c'est la fenêtre du deuxième fichier qui s'affiche... (regardez la ligne 56)
    Voici mon code, pourriez-vous m'aider s'il vous plait ? Merci
    Code python : 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
    164
    165
    166
    167
    168
    # -*- coding: utf-8 -*-
    """
    Created on Jully 2017
     
    @author: Anon
    """
     
    from tkinter import Frame, Tk, BOTH, Text, Menu, END, Toplevel
    import tkinter.filedialog as diag
    import tkinter.ttk as ttk
    import os
     
    def save(file): 
        saver = open('saver.txt', 'a+')#os.popen('attrib +h ' + saver)
        saver.seek(0)
        content = saver.readlines()
        toSave = file
        if not content:#check if empty
            saver.write(toSave)
        else:
            newContent = '\n'+toSave
            saver.write(newContent)
        saver.close()
     
    def removeFile(win, bt, file):
        with open('saver.txt', 'a+') as saver:
            saver.seek(0)
            content = saver.readlines()
        remove = str(os.path.abspath(file).replace('\\', '/'))
        for k in range (0, len(content)):
            content[k] = content[k].replace('\n','')
        content.remove(remove)
        newContent = ''
        for k in range(0, len(content)):
            newContent += content[k]
        os.remove('saver.txt')
        saver = open('saver.txt', 'a+')
        saver.seek(0)
        saver.write(newContent)
        bt.pack_forget()
        win.destroy()
     
    def openWin(text, title, root):
        win4 = Toplevel(root)
        win4.txt = Text(win4)
        win4.txt.pack(fill=BOTH, expand=1)
        win4.txt.insert(END, text)
        bouton = ttk.Button(win4, text = "Close", command=win4.destroy)
        bouton.pack()
        h = win4.winfo_screenheight()
        w = win4.winfo_screenwidth()
        win4.geometry(str(int(w/1.5))+'x'+str(int(h/1.5))+'+'+str(int((w-(w/1.5))/2))+'+'+str(int((h-(h/1.5))/3)))
        win4.title('Mon prog - '+title)
     
    def fileStats(file, root, btRm):
        print('#fileStats: ',file,root,btRm)#Mauvais affichage....
        win2 = Toplevel(root)
        fileName = str(file).split('/')[-1].split('.')[0]
        lb = ttk.Label(win2, width=300, text=fileName, anchor="center")
        lb.pack()
        bt = ttk.Button(win2, text="Details", command=lambda:openDetails(file, root))
        bt.pack(fill='x')
        bt = ttk.Button(win2, text="Remove file from list", command=lambda:removeFile(win2, btRm, file))
        bt.pack(fill='x', side='bottom')
        bt = ttk.Button(win2, text="Close", command=win2.destroy)
        bt.pack(fill='x', side='bottom')
        win2.geometry("250x220+150+150")
        win2.title('Mon prog')
     
    def openDetails(file, root):
        win3 = Toplevel(root)
        win3.txt = Text(win3)
        win3.txt.pack(fill=BOTH, expand=1)
        f = open(file, "rb")
        text = f.readlines()
        f.close()
        page = ''
        for k in range(0, len(text)):
            page += text[k].decode('gb2312','ignore')
        win3.txt.insert(END, page)
        bouton = ttk.Button(win3, text = "Close", command=win3.destroy)
        bouton.pack()
        h = win3.winfo_screenheight()
        w = win3.winfo_screenwidth()
        win3.geometry(str(int(w/1.5))+'x'+str(int(h/1.5))+'+'+str(int((w-(w/1.5))/2))+'+'+str(int((h-(h/1.5))/3)))
        win3.title('Mon prog - '+str(file).split('/')[-1].split('.')[0]+' - Details')
     
    class Example(Frame):
     
        def __init__(self, parent):
            Frame.__init__(self, parent)   
     
            self.parent = parent
            self.initUI()
     
        def initUI(self):
     
            btList = []
     
            self.parent.title("Mon prog")
            self.pack(fill=BOTH, expand=1)
     
            saver = open('saver.txt', 'a+')
            saver.seek(0)
            content = saver.readlines()
            saver.close()
     
            if not content:#check if empty
                lb = ttk.Label(self, width=300, text="No file", anchor="center")
                lb.pack()
            else:
                lb = ttk.Label(self, width=300, text="Your files", anchor="center")
                lb.pack()
                for k in range(0, len(content)):
                    if content[k] != '\n' and content[k] != '\r' and content[k] != '\r\n':
                        path = content[k].replace('\r\n','')
                        path = content[k].replace('\n','')
                        fileShort = path.split('/')[-1]
                        fileName = fileShort.split('.')[0]
                        bouton = ttk.Button(self, text=fileName)
                        bouton.pack(fill='x')
                        bouton.config(command=lambda:fileStats(fileShort, self, bouton))               
                        print(k,'#',fileShort,bouton)#jai un bon affichage
                        btList.append(bouton)
     
            for k in range(0, len(btList)):
                print('#Liste: ',btList[k].cget("command"))#affichage correct
     
            menubar = Menu(self.parent)
            fileMenu = Menu(menubar, tearoff=0)
     
            fileMenu.add_command(label="Open", command=lambda:self.onOpen(lb))
            menubar.add_cascade(label="File", menu=fileMenu)
            self.parent.config(menu=menubar)        
     
        def onOpen(self, lb):
            ftypes = [('Text files', '*.txt'), ('All files', '*')]
            dlg = diag.Open(self, filetypes = ftypes)
            fl = dlg.show()
     
            if fl != '':
                if lb.cget("text") == 'No file':
                    lb.config(text="Your files")
                saver = open('saver.txt', 'a+')
                saver.seek(0)
                content = saver.readlines()
                saver.close()
                content = [x.replace('\n','') for x in content]
                if fl not in content:
                    fileName = str(fl).split('/')[-1].split('.')[0]
                    bouton = ttk.Button(self, text=fileName)
                    bouton.pack(fill='x')
                    bouton.config(command=lambda:fileStats(fl, self, bouton))
                    save(fl)
     
        def readFile(self, filename):
            f = open(filename, "r")
            text = f.read()
            return text        
     
    def main():
        root = Tk()
        ex = Example(root)
        root.geometry("250x300+100+100")
        root.mainloop()
     
    if __name__ == '__main__':
        main()

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

    Relisez votre ligne 122... Et réfléchissez un peu avec l'aide de l'interpréteur Python:
    Une fonction simple avec un paramètre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> def f(n):
    ...     print (n)
    ...
    Puis une fonction g construite avec lambda:
    Si on appelle g() sans avoir définit "i":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> g()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 1, in <lambda>
    NameError: name 'i' is not defined
    >>>
    Et si on définit "i":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> i = 0
    >>> g()
    0
    >>> i = 10
    >>> g()
    10
    Çà prend toujours la dernière valeur.
    Vous imaginez bien qu'un truc aussi étrange va piéger tout débutant et qu'il doit être mentionné quelque part dans la FAQ.
    Bonne lecture.

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

  3. #3
    Membre très actif
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 299
    Par défaut
    Super merci beaucoup,
    Certes ça prend la dernière valeur quand on modifie i mais le bouton est censé être avec un i brut, je veux dire que dans ma boucle je demande a packer des boutons avec des arguments différents. Dois je faire une fermeture ?
    Je comprends pas, pourquoi il y a écrit " # elle ne prend AUCUN ARGUMENT dans sa définition;" alors qu'elle a l'argument "valeur" ? Comment faire passer la fenêtre et le bouton pour qu'ils soient récupérés svp ?

    Je suis perdu, j'ai fait ça mais j'ai une erreur :
    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
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    # -*- coding: utf-8 -*-
    """
    Created on Jully 2017
     
    @author: Anon
    """
     
    from tkinter import Frame, Tk, BOTH, Text, Menu, END, Toplevel
    import tkinter.filedialog as diag
    import tkinter.ttk as ttk
    import os
     
    # on définit une fermeture
    def fermeture (root, file, bouton):
        # on définit ici la vraie fonction qui fait le traitement attendu;
        # comme cette fonction sera appelée par le bouton cliquable
        # elle ne prend AUCUN ARGUMENT dans sa définition;
        # en revanche, elle va se servir des arguments stockés dans
        # la fermeture (c'est tout l'intérêt du truc);
        def mon_traitement (file, root, btRm):
            win2 = Toplevel(root)
            fileName = str(file).split('/')[-1].split('.')[0]
            lb = ttk.Label(win2, width=300, text=fileName, anchor="center")
            lb.pack()
            bt = ttk.Button(win2, text="Details", command=lambda:openDetails(file, root))
            bt.pack(fill='x')
            bt = ttk.Button(win2, text="Remove file from list", command=lambda:removeFile(win2, btRm, file))
            bt.pack(fill='x', side='bottom')
            bt = ttk.Button(win2, text="Close", command=win2.destroy)
            bt.pack(fill='x', side='bottom')
            win2.geometry("250x220+150+150")
            win2.title('Mon prog')
            # on exploite l'argument stocké par la fermeture
            #resultat.set("Vous avez cliqué sur le bouton du fichier '{}'".format(file))
        # end def
        # retourne une fonction en résultat
        return mon_traitement (root, file, bouton)
    # end def
     
    def save(file): 
        saver = open('saver.txt', 'a+')#os.popen('attrib +h ' + saver)
        saver.seek(0)
        content = saver.readlines()
        toSave = file
        if not content:#check if empty
            saver.write(toSave)
        else:
            newContent = '\n'+toSave
            saver.write(newContent)
        saver.close()
     
    def removeFile(win, bt, file):
        with open('saver.txt', 'a+') as saver:
            saver.seek(0)
            content = saver.readlines()
        remove = str(os.path.abspath(file).replace('\\', '/'))
        for k in range (0, len(content)):
            content[k] = content[k].replace('\n','')
        content.remove(remove)
        newContent = ''
        for k in range(0, len(content)):
            newContent += content[k]
        os.remove('saver.txt')
        saver = open('saver.txt', 'a+')
        saver.seek(0)
        saver.write(newContent)
        bt.pack_forget()
        win.destroy()
     
    def openWin(text, title, root):
        win4 = Toplevel(root)
        win4.txt = Text(win4)
        win4.txt.pack(fill=BOTH, expand=1)
        win4.txt.insert(END, text)
        bouton = ttk.Button(win4, text = "Close", command=win4.destroy)
        bouton.pack()
        h = win4.winfo_screenheight()
        w = win4.winfo_screenwidth()
        win4.geometry(str(int(w/1.5))+'x'+str(int(h/1.5))+'+'+str(int((w-(w/1.5))/2))+'+'+str(int((h-(h/1.5))/3)))
        win4.title('Mon prog - '+title)
     
    def openDetails(file, root):
        win3 = Toplevel(root)
        win3.txt = Text(win3)
        win3.txt.pack(fill=BOTH, expand=1)
        f = open(file, "rb")
        text = f.readlines()
        f.close()
        page = ''
        for k in range(0, len(text)):
            page += text[k].decode('gb2312','ignore')
        win3.txt.insert(END, page)
        bouton = ttk.Button(win3, text = "Close", command=win3.destroy)
        bouton.pack()
        h = win3.winfo_screenheight()
        w = win3.winfo_screenwidth()
        win3.geometry(str(int(w/1.5))+'x'+str(int(h/1.5))+'+'+str(int((w-(w/1.5))/2))+'+'+str(int((h-(h/1.5))/3)))
        win3.title('Mon prog - '+str(file).split('/')[-1].split('.')[0]+' - Details')
     
    class Example(Frame):
     
        def __init__(self, parent):
            Frame.__init__(self, parent)   
     
            self.parent = parent
            self.initUI()
     
        def initUI(self):
     
            btList = []
     
            self.parent.title("Mon prog")
            self.pack(fill=BOTH, expand=1)
     
            saver = open('saver.txt', 'a+')
            saver.seek(0)
            content = saver.readlines()
            saver.close()
     
            if not content:#check if empty
                lb = ttk.Label(self, width=300, text="No file", anchor="center")
                lb.pack()
            else:
                lb = ttk.Label(self, width=300, text="Your files", anchor="center")
                lb.pack()
                for k in range(0, len(content)):
                    if content[k] != '\n' and content[k] != '\r' and content[k] != '\r\n':
                        path = content[k].replace('\r\n','')
                        path = content[k].replace('\n','')
                        fileShort = path.split('/')[-1]
                        fileName = fileShort.split('.')[0]
                        bouton = ttk.Button(self, text=fileName)
                        bouton.pack(fill='x')
                        bouton.config(command=fermeture(self, fileShort, bouton))               
                        print(k,'#',fileShort,bouton)#jai un bon affichage
                        btList.append(bouton)
     
            for k in range(0, len(btList)):
                print('#Liste: ',btList[k].cget("command"))#affichage correct
     
            menubar = Menu(self.parent)
            fileMenu = Menu(menubar, tearoff=0)
     
            fileMenu.add_command(label="Open", command=lambda:self.onOpen(lb))
            menubar.add_cascade(label="File", menu=fileMenu)
            self.parent.config(menu=menubar)        
     
        def onOpen(self, lb):
            ftypes = [('Text files', '*.txt'), ('All files', '*')]
            dlg = diag.Open(self, filetypes = ftypes)
            fl = dlg.show()
     
            if fl != '':
                if lb.cget("text") == 'No file':
                    lb.config(text="Your files")
                saver = open('saver.txt', 'a+')
                saver.seek(0)
                content = saver.readlines()
                saver.close()
                content = [x.replace('\n','') for x in content]
                if fl not in content:
                    fileName = str(fl).split('/')[-1].split('.')[0]
                    bouton = ttk.Button(self, text=fileName)
                    bouton.pack(fill='x')
                    bouton.config(command=lambda:fileStats(fl, self, bouton))
                    save(fl)
     
        def readFile(self, filename):
            f = open(filename, "r")
            text = f.read()
            return text        
     
    def main():
        root = Tk()
        ex = Example(root)
        root.geometry("250x300+100+100")
        root.mainloop()
     
    if __name__ == '__main__':
        main()
    File "C:/Users/Anon/.spyder-py3/AssetsManagement/aide.py", line 134, in initUI
    bouton.config(command=fermeture(self, fileShort, bouton))

    File "C:/Users/Anon/.spyder-py3/AssetsManagement/aide.py", line 37, in fermeture
    return mon_traitement (root, file, bouton)

    File "C:/Users/Anon/.spyder-py3/AssetsManagement/aide.py", line 21, in mon_traitement
    win2 = Toplevel(root)

    File "C:\Users\Anon\Anaconda3\lib\tkinter\__init__.py", line 2336, in __init__
    BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra)

    File "C:\Users\Anon\Anaconda3\lib\tkinter\__init__.py", line 2286, in __init__
    BaseWidget._setup(self, master, cnf)

    File "C:\Users\Anon\Anaconda3\lib\tkinter\__init__.py", line 2256, in _setup
    self.tk = master.tk

    AttributeError: 'str' object has no attribute 'tk'

  4. #4
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 064
    Par défaut
    C'est un peu le "bordel" dans votre tête, des choses incohérentes apparaissent... Posez-vous les bonnes questions, comme par exemple votre fonction removeFile:
    Que devrait-elle prendre comme argument(s) ?
    Ne fait-elle que supprimer le fichier comme son nom l'indique ?

    Vous utilisez ou plutôt intégrez une fonction dans une autre fonction (mon_traitement dans fermeture), pourquoi ? C'est une manière de faire quasi inexistante...

    Dans votre premier code, ligne 122, fileStats est censé donné des statistiques sur un fichier:
    Est-ce le cas ?
    Pourquoi un objet Button fait-il partie des arguments de cette fonction ?

    Et beaucoup d'autres remarques seraient à dire, mais ça devient trop nombreux, posez-vous, prenez un papier et représentez un schéma type UML en indiquant les entités présentes, leurs fonctions et les interactions entre elles.

    Bon courage...

    P.S: Pour votre problème, vous liez chaque paramètre de votre fonction lambda quand elle est appelée, mais pas quand elle est créée... Si vous voulez des paramètres indépendants, il faut l'exprimer d'une certaine manière,


  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 754
    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 754
    Par défaut
    Citation Envoyé par Anonyme1784 Voir le message
    je veux dire que dans ma boucle je demande a packer des boutons avec des arguments différents. Dois je faire une fermeture ?
    Oui mais une fermeture retourne une fonction et non le résultat de son exécution (relisez l'article de la FAQ). De plus, si vous vous plantez dans l'ordre ou la nature des arguments passés, çà se passera comme pour toute fonction.
    Et pas la peine de poster vos 180 lignes de code pour illustrer çà...

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

  6. #6
    Membre très actif
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    299
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 299
    Par défaut
    Si je mets
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    command=lambda arg=machin:fonction(machin)
    ca fonctionne.

  7. #7
    Membre très actif

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Billets dans le blog
    1
    Par défaut
    Plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    command=lambda arg=machin:fonction(arg)
    Car sinon, cela n'a aucun intérêt, et reviendra au problème de base que tu avais.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 14/12/2016, 05h53
  2. [Batch] Connexion SFTP + download de tous les fichiers ET tous les répertoires
    Par gazza dans le forum Scripts/Batch
    Réponses: 2
    Dernier message: 06/03/2014, 13h45
  3. lister tous les membres de tous les groupes AD
    Par fbb53 dans le forum VBScript
    Réponses: 1
    Dernier message: 03/10/2011, 11h24
  4. Réponses: 9
    Dernier message: 16/10/2006, 16h35
  5. Réponses: 1
    Dernier message: 19/08/2006, 10h27

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