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 :

[Python 3.5] [Débutant] Problème de compréhension de sleep


Sujet :

Python

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Orne (Basse Normandie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2017
    Messages : 6
    Points : 5
    Points
    5
    Par défaut [Python 3.5] [Débutant] Problème de compréhension de sleep
    Bonjour à tous,

    j'essaie de créer une pause dans une fonction, et d'après mes recherches, il faut utiliser la fonction sleep du module time. La pause en elle-même fonctionne bien, mais je ne comprends pas une chose. Voici un exemple de code pour illustrer mon interrogation :

    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
    #essai
    import tkinter as tk
    import time
     
    def fonctionAffiche():
        monMessage.place(x = 10, y = 10)
        time.sleep(2)
        maFenetre.destroy()
     
    maFenetre = tk.Tk()
    maFenetre.geometry("500x120")
     
    monBouton = tk.Button(maFenetre, width=10, text = "Ok", command=fonctionAffiche)
    monMessage = tk.Label(maFenetre, text = "Je veux afficher ce message durant 2 secondes")
     
    monBouton.place(x = 210, y = 90)
    J'ai fait ce code spécifiquement pour illustrer mon problème de compréhension. Je créée simplement une fenêtre, un bouton et un label. Lorsque le clique sur le bouton, je veux afficher le label durant 2 secondes, puis la fenêtre se ferme. Seulement, lorsque je clique sur le bouton, on sent bien la pause (le bouton se fige en position "appuyée") mais le message ne s'est pas affiché avant. Et ma question est là : pourquoi le label ne s'affiche pas avant la pause? Je ne sais même pas s'il s'affiche après mais trop brièvement pour que je ne le vois... mais dans mon esprit, vu que la ligne d'affichage du label se situe avant la pause, on aurait dû la voir avant la pause non?

    Donc visiblement, quelque chose m'échappe, et mes recherches sur le net ne donnent pas grand chose. Si vous avez l'explication, je suis tout ouïe! Merci d'avance.

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

    Citation Envoyé par majestyofgaia Voir le message
    Donc visiblement, quelque chose m'échappe, et mes recherches sur le net ne donnent pas grand chose. Si vous avez l'explication, je suis tout ouïe!
    fonctionAffiche est une fonction particulière appelée "callback"... elle ne provoque pas des mises à jour immédiate de l'affichage mais poste une suite d'autres callbacks exécutés par le GUI lorsqu'il pourra leur donner la main. Si vous mettez un time.sleep, le callback se fera terminera plus tard et les mises à jour aussi.
    Les tutos. sont là pour expliquer comment fonctionne la programmation évènementielle et faire les premiers pas.

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

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Orne (Basse Normandie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2017
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Merci pour la réponse.

    J'avais déjà lu ce tutoriel, mais je vais me replonger dedans. A l'époque, des choses m'avaient échappées (trop techniques pour moi). Je vais me concentrer sur cet aspect.

    Merci encore.

  4. #4
    Membre confirmé
    Homme Profil pro
    Développeur banc de test
    Inscrit en
    Mai 2014
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur banc de test
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2014
    Messages : 199
    Points : 482
    Points
    482
    Par défaut
    Bonjour,

    Tkinter utilise son propre fonctionnement d'attente.
    sleep va se contenter d'attendre en dehors du thread et à aucun moment durant cette attente il ne pourra mettre à jour le message.

    Tkinter dispose de plusieurs moyens d'attendre ou carrément de forcer la mise à jour.

    Pour demander explicitement la mise à jour d'un widget/groupe/fenêtre :

    .update()
    Processes all pending events, calls event callbacks, completes any pending geometry management, redraws widgets as necessary, and calls all pending idle tasks.
    Source : effbot.org/tkinterbook

    .update_idletasks()
    Calls all pending idle tasks, without processing any other events.
    Source : effbot.org/tkinterbook

    Ensuite pour attendre un temps donné ou le temps qu'une opération se termine :

    .after(delay_ms, callback=None, *args)
    Registers an alarm callback that is called after a given time.
    Source : effbot.org/tkinterbook

    .after_idle(callback, *args)
    Registers a callback that is called when the system is idle.
    Source : effbot.org/tkinterbook

    Voici ce que ça donne en utilisation :

    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
    # Python 3
     
    import tkinter as tk
    import time
     
    def fonctionAffiche():
        monMessage.place(x = 10, y = 10)
        monMessage.update_idletasks() # Force la mise à jour du wdiget Label
        maFenetre.after(2000, fonction_fermerture) # Attend 2 secondes puis appelle fermeture
     
    def fonction_fermerture():
        maFenetre.destroy()
     
    maFenetre = tk.Tk()
    maFenetre.geometry("500x120")
     
    monBouton = tk.Button(maFenetre, width=10, text = "Ok", command=fonctionAffiche)
    monMessage = tk.Label(maFenetre, text = "Je veux afficher ce message durant 2 secondes")
     
    monBouton.place(x = 210, y = 90)

  5. #5
    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 YCL-1 Voir le message
    Tkinter utilise son propre fonctionnement d'attente.
    sleep va se contenter d'attendre en dehors du thread et à aucun moment durant cette attente il ne pourra mettre à jour le message.
    bloquer les mises à jour, c'est peut être ce qu'on veut:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def fonctionAffiche():
        monMessage.place(x = 10, y = 10)
        maFenetre.update_idletasks() 
        time.sleep(2)
        maFenetre.destroy()
    Sinon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def fonctionAffiche():
        monMessage.place(x = 10, y = 10)
        maFenetre.after(2000, maFenetre.destroy)
    ne bloquera pas les éventuels appels répétés à fonctionAffiche suite à plusieurs click sur "Ok".

    Dans tous les cas, il faut comprendre ce qu'est la mainloop (et la programmation événementielle) pour savoir quoi appliquer.

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

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Orne (Basse Normandie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2017
    Messages : 6
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par YCL-1 Voir le message
    Ensuite pour attendre un temps donné ou le temps qu'une opération se termine :

    .after(delay_ms, callback=None, *args)
    Registers an alarm callback that is called after a given time.
    Source : effbot.org/tkinterbook

    .after_idle(callback, *args)
    Registers a callback that is called when the system is idle.
    Source : effbot.org/tkinterbook
    Merci pour ces éléments, ils sont vraiment intéressants. Par rapport à ce que je recherchais, ils solutionnent mon problème.


    ne bloquera pas les éventuels appels répétés à fonctionAffiche suite à plusieurs click sur "Ok".

    Dans tous les cas, il faut comprendre ce qu'est la mainloop (et la programmation événementielle) pour savoir quoi appliquer.
    C'est une chose à laquelle je n'avais pas pensé. Je pense comprendre la différence entre l'utilisation d'un sleep et celle d'un .after.

    Dans tous les cas, il faut comprendre ce qu'est la mainloop (et la programmation événementielle) pour savoir quoi appliquer.
    Oui, je comprends, mais dans mon cas c'est ce genre d'"obstacles" qui me font progresser dans la compréhension. Parfois, je pense comprendre, mais ma vision est erronée. Et quand ça ne marche pas, là je déchante! ^^ J'imagine que je ne suis pas le seul comme ça.

    En tout cas merci pour ces informations, elles répondent parfaitement à mes attentes.

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

Discussions similaires

  1. Débutant : Problème de compréhension d'un script
    Par developman dans le forum Shell et commandes GNU
    Réponses: 3
    Dernier message: 12/04/2011, 22h20
  2. [Débutant] Problème compréhension code XAML
    Par JolyLoic dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 26/08/2009, 17h00
  3. [Débutant] Problème de compréhension?
    Par k o D dans le forum Servlets/JSP
    Réponses: 5
    Dernier message: 25/10/2007, 08h48
  4. [Débutant] Problème de compréhension
    Par Invité dans le forum Langage
    Réponses: 4
    Dernier message: 09/11/2006, 13h06
  5. [Débutant] problème de compréhension
    Par Sylvester dans le forum Général Java
    Réponses: 18
    Dernier message: 21/07/2005, 09h16

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