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

Tkinter Python Discussion :

Soulager le programme pour eviter les freezes


Sujet :

Tkinter Python

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 60
    Points : 38
    Points
    38
    Par défaut Soulager le programme pour eviter les freezes
    Salut

    Je développe un viewer de jpg pour afficher sur un ecran en pleine ecran avec plusieurs info

    meteo
    heure
    donne sql

    etc etc


    En sois la fenetre principale ne charge que des photos ou valeurs

    La mise a jour de la liste des photos ou valeurs prend un temps assez long qui freeze le deroulement de la fenetre principale

    comment puis je alleger la chose

    un python qui affiche la fenetre et lit des listes tout les 5s

    un autre python qui lui s'occupe de mettre a jour les listes et les renvoyer dans le premier python

    genre threads je pense

    auriez vous un petit exemple a me donner

    Merci de votre aide

  2. #2
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut
    Salut,

    Tu es en train de découvrir les applis graphiques avec leurs contraintes. Ce qu'il se passe en fait, c'est que l'IHM attend que ton traitement soit fini avant de continuer. Pourquoi? parque ton IHM et ton backend (ta tache de fond) partage le même thread.

    Pour une appli du genre calculatrice, cela ne pose aucun soucis. Mais dès que cela se complique un peu, tu dois passer au multi thread/threading ou multiprocessing. Il y a des librairies Python pour cela (thread, threading, multiprocessing). Sur les deux premieres, une est officiellement depreciees, et on recommand d'utiliser l'autre (desole, je ne me rappelle plus laquelle). Personellement, j'utilise la multiprocessing, car elle permet de tirer pleinement profit des processeurs multicoeurs.

    Les threads communiquent entre eux par flag. Les multiprocess par flag, pipe, queues. Par pipe/queue, on peut egalement transmettre des objets, ce qui s'avere tres pratique.

    Mais attention toutefois, car un thread n'est pas un processus. De fait, le fonctionnement ne sera pas le même. Par exemple, un multi thread va durer un temps X pour s'executer, mais avec des taches ne monopolisant pas plus de 30% (par exemple) de processeur au maximum. Par contre, un multiprocess va mettre une durée X/10 (par exemple) avec tous les processeurs alloués à 100%.

    Ce que je veux mettre en evidence ici, c'est que tu dois distinguer, pour commencer, la difference thread/process, et ensuite choisir ce qu'il te convient le mieux.
    "La connaissance appartient à tout le monde" (Film Antitrust)

    Tout le nécessaire pour Python:
    *News/Accueil *Cours/tutoriels *FAQ
    *Forums *Outils dédiés *Mon espace personnel avec mes Articles, Cours et Tutoriels

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 60
    Points : 38
    Points
    38
    Par défaut Orthographe
    Merci.

    Pour ma part je souhaiterais mettre un place un processus ou thread avec un while true et un sleep qui va mettre à jour une liste globale que je pourrais donc récupérer dans mon affichage maître.

  4. #4
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut
    Alors tout d'abord jamais de "while True", car tu ne pourra jamais sortir. Il vaut mieux un "while <variable>", et mettre ta variable à True. Ainsi si tu desires sortir, tu aura juste à passer ta variable à False.

    Ensuite, effectivement, le sleep est indispensable si tu ne veut pas monopoliser le processeur. Meme une pause de 1 ms sera visible en terme d'utilisation ressource.

    Si tu utilises des threads, tu fonctionnera avec des flags qui peuvent te bloquer temporairement l'IHM. Il n'y aura plus de freeze, mais tu ne pourras pas forcement interagir avec. Avec le multiprocessing et le systeme de pipe, queues, tu peux mettre un process pour l'IHM, et un pour ton backend, et les faire communiquer via pipe/queue. Ton IHM sera insi toujours dispo, même si le resultat n'est pas immediat.

    PEtit precision, si tu utilises les pipes, choisit des modeles unidirectionnel, pour le côté securitaire. Les pipes sont de type unique. Si tu ecrit dedans, tu ecrase la donnée/l'objet précédent. Les queues sont par contre de type FIFO.
    "La connaissance appartient à tout le monde" (Film Antitrust)

    Tout le nécessaire pour Python:
    *News/Accueil *Cours/tutoriels *FAQ
    *Forums *Outils dédiés *Mon espace personnel avec mes Articles, Cours et Tutoriels

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    thread et GUI n'utilisent pas le même modèle de threading et le mélange est source de bugs.
    Ceci dit la forme de ce genre d'application est la suivante:
    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
    import tkinter as tk
    import threading
    import time
     
    done = threading.Event()
     
    def run_thread(count=5):
        while count > 0 and not done.is_set():
            post_update(count)
            time.sleep(0.5)
            count -= 1
        post_quit()
     
    def post_quit():
        app.after_idle(app.quit)
     
    def post_update(count):
        app.after_idle(lambda: display.configure(text=str(count)))
     
    def create_display(app=None):
        display = tk.Label(app, text='foo')
        return display
     
    if __name__ == '__main__':
     
        app = tk.Tk()
     
        display = create_display(app)
        display.pack()
     
        p = threading.Thread(target=run_thread, args=(5,))
        p.start()
     
        app.mainloop()
        done.set()
        p.join()
    La fonction exécutée dans la thread "poste" des mises à jour du GUI qui se traduisent par la soumission de l'appel d'un callback par la boucle évènementielle (du GUI). Avec tk ca passe par un appel à .after_idle, d'autres GUI utilisent des interfaces plus sophistiquées, mais le principe est le même: les mises à jour du GUI doivent se faire dans le thread du GUI (la thread principale du programme) car... un GUI est rarement ré-entrant.

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

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 60
    Points : 38
    Points
    38
    Par défaut
    Merci des infos

    Pour le moment je vais passer par des listes communes pour mettre a jour tkinter

    Un thread est lancer tout les x seconds qui lui ne touche en rien au gui mais met a jour une liste global sans lancer de modif sur un tk

    Et de l autre cote un un tk.after qui tourne est lit la liste globale et update le gui

    Cette facon peut elle fonctinner sans bug ?

    En attendant que je reecrive tout le programme

    Merci

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    Citation Envoyé par fennec62 Voir le message
    Un thread est lancer tout les x seconds qui lui ne touche en rien au gui mais met a jour une liste global sans lancer de modif sur un tk
    Lancer un thread toutes les x secondes qui... est plus coûteux que de lancer un threads qui attendra x secondes pour...

    Citation Envoyé par fennec62 Voir le message
    Et de l autre cote un un tk.after qui tourne est lit la liste globale et update le gui
    Cette facon peut elle fonctinner sans bug ?
    Tant que les mises à jour du GUI sont effectuées via des callbacks postés via .after, vous n'avez plus de "bug" côté design: çà fonctionne "sur le papier". Mais les bugs c'est quand vous allez "coder pour de vrai"...

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

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 60
    Points : 38
    Points
    38
    Par défaut
    Merci

    Pour le moment ca tiens

    Je tiens compte de toute ces remarques merci beaucoup

    J ai code le tout au fur et a mesure de mes pensees pour le moment

    Une fois tout valider je vais tenir compte de toute ces remarques puis obtimiser le code

    Encore merci

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Et bien, il ne vous reste qu'à marquer la discussion comme en cliquant sur le bouton en bas à gauche.

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

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 60
    Points : 38
    Points
    38
    Par défaut
    Encore deux petites questions

    Lorsque je lance un thread

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def majmeteo()
        global start,stop1
        While start==1:
             Meteo()
             Stop1=0
             Time.sleep(180)
         Stop1=1
     
     
     
    Meteo=Thread(target=majmeteo)
    Meteo.start()
    Quand je veux quitter mon gui je met donc ma variable start a 1 et j attend que ma variable stop1 soit a 0 pour faire un destroy
    Mais a chaque fois je dois attends max 180s sachant que je peux pas faire moins de temps sinon suis agressif sur le site ou je recupere la meteo

    Un moyen de tuer le thread ?

    Ou comment puis je faire pour afficher un message

    Fermeture en cours merci de patienter

    Sachant de j ai un canvas en grid et que je quit par un bind

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    def fin(event):
         Can.delete(ALL)
         Can.create_text(0,0,text="arret en cours")
         While stop1=0
             Time.sleep(2)
         Fen.destroy()
     
     
    Fen=Tk()
    Fen.bind('<Escape>',fin)
    Can=canvas(fen,1600,800)
    Can.grid(row=1)
    Fen.mainloop()
    Quand j appuie sur echap le gui se fige et attend stop1=1 avant de destroy mais aucun affichage du message

    Merci

  11. #11
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 812
    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 : 3 812
    Points : 7 097
    Points
    7 097
    Par défaut
    On ne peut pas utiliser une boucle comme ça dans une boucle événementielle (mainloop), avec Tkinter on utilise la méthode after
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  12. #12
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 60
    Points : 38
    Points
    38
    Par défaut
    Ok merci

    Je vais changer meme si ca marche pour le moment

    Et donc y a t il un moyen de tuer ce after instantanement a la suite d une commande

    Ou le destroy va tout detruire peut etre

    Merci

  13. #13
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par fennec62 Voir le message
    Et donc y a t il un moyen de tuer ce after instantanement a la suite d une commande

    Ou le destroy va tout detruire peut etre
    Relisez le bout de code que j'ai posté plus haut:
    Le thread:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def run_thread(count=5):
        while count > 0 and not done.is_set():
            post_update(count)
            time.sleep(0.5)
            count -= 1
        post_quit()
    teste un Event "done" qui sort de la boucle lorsqu'il est positionné.
    Côté GUI:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    if __name__ == '__main__':
     
        app = tk.Tk()
     
        display = create_display(app)
        display.pack()
     
        p = threading.Thread(target=run_thread, args=(5,))
        p.start()
     
        app.mainloop()
        done.set()
        p.join()
    Lorsque le GUI sort de la "mainloop", on positionne "done", puis on attend que le thread se termine.
    note: la sortie de la mainloop est ce que provoque l'appel à ".quit"...

    - W
    PS: on peut éviter le flag "done" en créant le thread avec l'option "daemon=True". Cela suppose qu'on peut détruire l'activité sans se préoccuper de son état et donc à utiliser avec modération.
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 60
    Points : 38
    Points
    38
    Par défaut
    Bon ...

    le code marche enfin un temps

    python.exe plante d'un seul coup aucune remonte d'erreur rien

    Mais bon je penche sincerement pour les threads

    voila un exemple de ce que je fait

    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
    import Tkinter
    from Tkinter import *
    from threading import Thread
    import threading
    import time
     
    done = threading.Event()
     
    def touch(event):
     
        fen.destroy()
     
     
    def go():
        global a,t,b,init
        can.delete(ALL)
     
        if init==1:
             a=b
             init=0
     
         if t<=len(a)-1:
             can.create_text(100,100, text=a[t], font="Cambria 18 bold", fill="gold")
              t+=1
              fen.after(1000,go)
         else:
           a=b
           t=0
           go()
     
    def var():
         global b,init
         c=1
         init=1
         while not done.is_set():
             c+=1
             b=range(c)
             time.sleep(5)
     
    a=[]
    b=[]
    init=0
    t=0
     
    fen=Tk()
    fen.bind('<Escape>', touch)
    can=Canvas(fen,width=w-w/4,height=h-h/10,highlightthickness=0,bg='white')
    can.grid(row=0)
     
    th=Thread(target=var)
    th.start()
     
    go()
     
    fen.mainloop()
    done.set()
    th.join()
    donc dans le principe le gui tourne et quand il a fini d afficher a il va recreer a avec b et se relance
    b etant genere en continu par le thread

    malheuresement python plante au bout d'un moment mais de facon aleatoire

    une idee

    merci

  15. #15
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    Postez du code qui fonctionne: si j'essaie d'exécuter votre exemple chez moi c'est plein d'erreur de syntaxe comme def go() sans ':' et j'en passe.
    malheuresement python plante au bout d'un moment mais de facon aleatoire
    Python à la bonne idée d'afficher un traceback qui donne pas mal d'information sur la cause du plantage.
    Les poster çà aide (notamment à s'assurer qu'on reproduit bien le même problème "ailleurs").

    - W
    PS: finalement, ce post n'est si "résolu" que çà...
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  16. #16
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 60
    Points : 38
    Points
    38
    Par défaut
    Oui desole j'ai tapé çà a l arrache hier sur l'ipad.

  17. #17
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Certes, mais çà ne donne pas plus d'infos.

    - W
    PS: je me suis permis de corriger l'orthographe du message précédent.
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  18. #18
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 60
    Points : 38
    Points
    38
    Par défaut
    Oui

    Mais dans l'absolue ce code peut il fonctionner avec la bonne syntaxe que j ai oublie ?


    Encore une question

    Le but de ce code est d afficher en diapo des jpg

    Il y a trois teles qui tournent et affiche les memes jpg

    Une fois que tkinter charge en memoire une image jpg y a t il un probleme si un autre tkinter charge le meme fichier sur une autre tele ? Le fichier est en reseau

    Merci

  19. #19
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par fennec62 Voir le message
    Mais dans l'absolue ce code peut il fonctionner avec la bonne syntaxe que j ai oublie ?
    Dans l'absolu, tout est SMOP (Simple Matter of Programming).
    Ceci dit le premier sujet est l'articulation entre le boulot qui est fait via des threads et des mises à jour de l'affichage géré par le GUI, ici tkinter.

    Citation Envoyé par fennec62 Voir le message
    Encore une question

    Le but de ce code est d afficher en diapo des jpg

    Il y a trois teles qui tournent et affiche les memes jpg

    Une fois que tkinter charge en memoire une image jpg y a t il un probleme si un autre tkinter charge le meme fichier sur une autre tele ? Le fichier est en reseau
    Lancer plusieurs fois un programme qui lit un fichier .jpg avec PIL et l'affiche via tkinter se teste assez facilement.
    Par contre, "ouvrir un fichier en réseau" suppose du NAS ou un accès HTTP: rien de bien méchant mais probablement d'autres sujets à discuter lorsque vous en serez à coder la chose.

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

Discussions similaires

  1. créér un trigger pour eviter les doublons
    Par jupierre dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 04/09/2008, 11h48
  2. comment faire un programme pour trier les hommes et les femmes
    Par oudin77 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 20/05/2008, 16h14
  3. Programmer pour toutes les résolutions d'écran
    Par marcello2 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 20/02/2007, 14h42
  4. [CSS] balise div et css pour eviter les framesets
    Par jfjava2002 dans le forum Mise en page CSS
    Réponses: 1
    Dernier message: 24/03/2006, 11h56
  5. existe t 'il des programme pour transformer les bases
    Par creazone dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 05/10/2004, 14h11

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