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 :

message d'erreur à la fermeture


Sujet :

Tkinter Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Par défaut message d'erreur à la fermeture
    Comment éviter le message d'erreur à la fermeture sur cet exemple simple :

    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
     
    import tkinter as tk
    ok=True
     
    def incremente():
        global compteur
        compteur += 1
        compteur_lbl['text'] = str(compteur)
        if ok:
            app.after(1000, incremente)
     
     
     
    app = tk.Tk()
    compteur = 0
     
    compteur_lbl = tk.Label(app, text=str(compteur), font=("", 16))
    compteur_lbl.grid(padx=8, pady=8)
    app.after(1000, incremente)
     
     
    def quitter():
        global ok
        ok=False
        app.destroy()
     
     
    app.protocol('WM_DELETE_WINDOW', quitter)
    app.mainloop()
    message dans mu-editor :
    >>> invalid command name "2195026287624incremente"
    while executing
    "2195026287624incremente"
    ("after" script)
    Merci (j'ai le même problème avec l'utilisation d'un thread pour le timer...)

  2. #2
    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,

    Vous comprenez ce que raconte l'erreur? Si le Label a été détruit, lorsque la fonction déclenchée par .after essaie de le mettre à jour... erreur.

    Après la question est de savoir pourquoi le bidouillage que vous avez fabriqué avec la variable OK ne fonctionne pas.
    Relisez votre code: la variable ne contrôle que l'instruction .after i.e. l’ordonnancement d'une opération qui se déclenchera dans une seconde (que l'application ait été détruite ou pas d'ici là).

    note: jetez aussi un œil à after_cancel

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

  3. #3
    Membre Expert
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Par défaut
    Salut,

    j'avais déjà testé la méthode after_cancel(id), sans succès... Il fallait déclarer timer en global dans la procédure appelée chaque seconde :
    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
     
    import tkinter as tk
     
    def incremente():
        global compteur
        global timer  # ici  sinon ça plante avec mu et pas sous pyzo....  L'encapsulation est étrange en python... l'instruction global n'est pas la + heureuse.
        compteur += 1
        compteur_lbl['text'] = str(compteur)
        timer=app.after(1000, incremente)
     
    app = tk.Tk()
    compteur = 0
     
    compteur_lbl = tk.Label(app, text=str(compteur), font=("", 16))
    compteur_lbl.grid(padx=8, pady=8)
    timer=app.after(1000, incremente)
     
     
     
    def quitter():
        app.after_cancel(timer)
        app.destroy()
     
     
    app.protocol('WM_DELETE_WINDOW', quitter)
    app.mainloop()

  4. #4
    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 Archimède Voir le message
    j'avais déjà testé la méthode after_cancel(id), sans succès... Il fallait déclarer timer en global dans la procédure appelée chaque seconde.
    Alors problème résolu?

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

  5. #5
    Membre Expert
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Par défaut
    Oui, excuse...
    J'avais déjà testé after_cancel(id) sur mon code qui posait problème mais je l'utilisais sur un objet d'une classe qui dérivait de canvas....
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    monobjet.after_cancel(timer)
    et j'avais un message d'erreur à la fermeture de l'application...
    En faisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fen .after_cancel(timer)
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    monObjet.after_cancel(timer)
    , plus de problème... et le dans la procédure appelée à chaque intervaltimer qui fait aussi planter sous mu-editor si pas déclaré...
    Si ça peut servir pour un autre...

    A+ et merci encore

  6. #6
    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,

    Vous devez être "cohérent" avec le widget utilisé pour soumettre les .after et celui utilisé pour .after_cancel.

    Dérrière .after, il y a la création d'une variable Tk associée à l'objet qui réalise le callback a appeler. Cette variable (Tk) est l'identifiant retourné par .after, il est "global".
    Mais l'objet à appeler est stocké côté widget.

    .after_cancel appliqué à n'importe quel autre widget (que celui utilisé pour .after) va supprimer le côté Tk, mais ne change pas le côté tkinter. Lorsque destroy fait le ménage, il demande à Tk de détruire quelque chose qui n'existe plus.
    Exemple:
    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
    >>> import tkinter as tk
    >>> root = tk.Tk()
    >>> w = tk.Label()
    >>> z = tk.Label()
    >>> w.after(10000, print, 'toto')
    'after#0'
    >>> z.after_cancel('after#0')
    >>> w.destroy()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "C:\py_env\py64_38\lib\tkinter\__init__.py", line 2578, in destroy
        Misc.destroy(self)
      File "C:\py_env\py64_38\lib\tkinter\__init__.py", line 630, in destroy
        self.tk.deletecommand(name)
    _tkinter.TclError: can't delete Tcl command
    Par contre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> w = tk.Label()
    >>> w.after(10000, print, 'toto')
    'after#1'
    >>> w.after_cancel('after#1')
    >>> w.destroy()
    >>>
    - 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. Message d'erreur à la fermeture d'une fenêtre
    Par Pascal Lob dans le forum VB.NET
    Réponses: 5
    Dernier message: 16/11/2011, 11h20
  2. Message d'erreur à la fermeture de la base
    Par theuma dans le forum Runtime
    Réponses: 4
    Dernier message: 16/06/2011, 08h21
  3. message d'erreur à la fermeture
    Par nefertari dans le forum Delphi
    Réponses: 10
    Dernier message: 12/07/2007, 07h25
  4. Message d'erreur à la fermeture d'une page web
    Par WELCOMSMAIL dans le forum Autres Logiciels
    Réponses: 2
    Dernier message: 26/04/2006, 17h12

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