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 :

Multithreading et fermeture de fenêtre TK


Sujet :

Tkinter Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2014
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2014
    Messages : 10
    Points : 11
    Points
    11
    Par défaut Multithreading et fermeture de fenêtre TK
    Bonjour à tous!
    Pour les besoins d'un projet, j'ai fait un minuteur, qui est censé fermer la fenêtre TK une fois le temps écoulé. J'ai utilisé un thread à part pour fluidifier le programme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    class ThreadMinuteur(threading.Thread):
        def __init__(self,fen):
            threading.Thread.__init__(self)
            self.fen=fen
     
        def run(self):
            while self.fen.m>0:
                time.sleep(1)
                self.fen.m-=1
     
            self.fen.destroy()
    Le problème arrive au niveau de la commande destroy(). En fait, la fenêtre en elle-même reste ouverte même si les boutons qui y figurent ne sont plus accessibles. Mais pour l'interpréteur, la fenêtre est bel et bien fermée (des chevrons réapparaissent une fois le temps écoulé). Je ne comprends pas vraiment ce qui se passe. J'ai creusé sur le web, mais sans succès. J'ai tenté d'isoler le thread par un lock().acquire() mais le résultat est le même.
    Merci de votre aide !

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Il y a longtemps que je n'ai pas travaillé avec tkinter, mais je me rappelle au moins d'une chose: tkinter n'est pas "thread-safe".

    Cela veut dire que le thread ne doit pas toucher aux objets graphiques. Il faut trouver un autre moyen pour que le thread communique avec le programme principal (qui devra fermer la fenêtre dans ton cas).
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2014
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2014
    Messages : 10
    Points : 11
    Points
    11
    Par défaut
    Merci pour ta réponse
    Je ne vois pas trop comment pouvoir communiquer avec le programme. J'avais essayé de mettre une boucle while dans la classe associée à la fenêtre, qui guettait le moment où self.m serait égal à 0. Le problème est qu'une fois entré dans la boucle, python arrête d’exécuter ce qui suit. Alors j'avais mis un autre Thread pointant vers cette boucle. Mais in fine, cela revient strictement au même. Un autre thread prend la place du premier pour achever la fenêtre.
    J'avais déjà créé un minuteur en utilisant une boucle récursive. J'essayais simplement avec le thread d'éviter les gros calculs associés à fen.after()...

    Sinon, il n'y a pas moyen d'utiliser un bind mais au lieu de mettre une touche du clavier, mettre quelque chose comme "self.m==0" ?

    Et aussi, je suis quand même assez étonné que Python ne soit pas safe-thread, sachant que j'utilise des thread ailleurs pour déplacer automatiquement des bonhommes et aussi pour un chronomètre. Et le tout fonctionne à merveille !

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

    Pas besoin de threads pour faire un minuteur:

    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
    >>> import tkinter as tk
    >>> def timer(left):
    ...     print (left)
    ...     if left > 0:
    ...        app.after(200, lambda z=left-1: timer(z))
    ...     else:
    ...        app.quit()
    ...
    >>> app = tk.Tk()
    >>> app.after(200, lambda: timer(5))
    'after#0'
    >>> 5
    4
    app.mainloop()
    3
    2
    1
    0
    Pas besoin parce que la plupart des GUI fonctionnent avec une event-loop. Un GUI intègre un threading coopératif. Il suffit à traiter la plupart des cas.
    Les threads systèmes sont préemptives. Elles sont indispensables lorsque le machin n'est pas "coopératif". En gros "pas coopératif", c'est ne pas arriver à libérer des cycles CPU évitant à l'utilisateur l'impression que son application est "figée". On confie alors à l'OS la responsabilité de pré-empter, libérer le CPU.

    Après désolé mais tk, _tkinter,... sont "thread safe" mais çà dépend des switchs de compilation et c'est un autre sujet.

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

  5. #5
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour wiztricks,

    Citation Envoyé par wiztricks Voir le message
    Après désolé mais tk, _tkinter,... sont "thread safe" mais çà dépend des switchs de compilation et c'est un autre sujet.
    Si je résume: tkinter est thread-safe, mais ce n'est pas sûr. J'avoue que je n'aime pas beaucoup ce genre de règle. En fait, il faut au moins que tk ait été construit avec l'option " --enable-threads". Est-ce le cas? Comment le savoir?

    Il existe même un projet de "tkinter-thread-safe" (http://tkinter.unpythonic.net/wiki/mtTkinter). Comme quoi le tkinter "normal" pose quelques problèmes sur ce point.

    Bref, il est raisonnable de ne pas compter dessus. D'autant plus si l'on développe un programme multiplateformes.

    Mais c'est dommage que ce ne soit pas clairement indiqué dans la documentation. Je n'ai rien trouvé, ni dans la doc de Python, ni dans celle de tkinter (la meilleure que je connais est celle-ci: http://infohost.nmt.edu/tcc/help/pub...web/index.html).
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    Mais c'est dommage que ce ne soit pas clairement indiqué dans la documentation. Je n'ai rien trouvé, ni dans la doc de Python, ni dans celle de tkinter (la meilleure que je connais est celle-ci: http://infohost.nmt.edu/tcc/help/pub...web/index.html).
    Python est thread-safe. Le GIL de CPython rend la plupart des changements sur les objets builtins tels que list, dict,... sont thread-safe. Mais dans la pratique, on évitera de créer des threads pour rien.
    Le cas échéant on sérialisera l'accès aux objets partagés par des verrous.
    Si on la joue aussi "parano", c'est parce qu'on sait que les "bugs" seront difficiles à reproduire, corriger,... même si la cause est due à une mauvaise utilisation/bug de la biblio.

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

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2014
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2014
    Messages : 10
    Points : 11
    Points
    11
    Par défaut
    Merci pour vos réponses !
    J'ai finalement rebasculé sur le minuteur avec self.after() comme le proposait Wiztricks.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par Arkey24 Voir le message
    J'ai finalement rebasculé sur le minuteur avec self.after() comme le proposait Wiztricks.
    Super.
    Plus besoin de se prendre le chou avec thread-safe ou pas, avec ce threading coopératif la sérialisation d'accès est "builtin" et bien plus facile à contrôler. Et ne parlons pas des performances/Watt.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

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

Discussions similaires

  1. [Javascript][VBScript]Détection de Fermeture de Fenêtre
    Par JohnBlatt dans le forum Windows
    Réponses: 1
    Dernier message: 24/01/2007, 16h09
  2. fermeture de fenêtre
    Par fontaigo dans le forum AWT/Swing
    Réponses: 2
    Dernier message: 15/04/2006, 21h17
  3. [WD9] Evénement de fermeture de fenêtre
    Par EpOnYmE187 dans le forum WinDev
    Réponses: 3
    Dernier message: 14/12/2005, 10h50
  4. ouverture et fermeture de fenêtre
    Par froggies dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 17/10/2005, 11h36
  5. opération sur fermeture de fenêtre
    Par java_math dans le forum Agents de placement/Fenêtres
    Réponses: 2
    Dernier message: 20/06/2004, 22h52

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