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 :

Boucle et Tk incompatibles ? [Python 3.X]


Sujet :

Python

  1. #1
    Membre régulier Avatar de scalpel
    Homme Profil pro
    Gestionnaire de parc micro-informatique
    Inscrit en
    Novembre 2008
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Gestionnaire de parc micro-informatique
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2008
    Messages : 148
    Points : 94
    Points
    94
    Par défaut Boucle et Tk incompatibles ?
    Bonjour à tous.tes,

    Pour créer des mouvements automatiques de Widgets dans un Canvas, j'utilisait jusqu'à présent une fonction que je réexécutait de façon ralentie et à l'infini avec : fen.after(100, maFonction). A la place de after(), je voudrait maintenant utiliser une boucle dans cette fonction en utilisant un sleep() pour la ralentir.

    La boucle tourne, j'ai vérifié avec un print() mais je n'affiche plus ma fenêtre ?
    Débutant en janvier 2024 l'apprentissage d'un langage de programmation et n'étant pas particulièrement doué, soyez indulgents.

  2. #2
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 817
    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 817
    Points : 7 110
    Points
    7 110
    Par défaut
    Bonjour,

    L'utilisation de time.sleep() dans une application Tkinter pour introduire des délais peut entraîner des problèmes de performance, notamment le gel de l'interface graphique.

    La méthode after() est préférée pour introduire un délai ou programmer une exécution répétée d'une fonction sans bloquer le thread principal.
    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)

  3. #3
    Membre expérimenté
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    870
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 870
    Points : 1 522
    Points
    1 522
    Billets dans le blog
    4
    Par défaut
    Bonjour,
    La boucle bloque le mainloop .
    Tu pourrais utiliser update_idletasks() pour obliger tkinter à mettre à jour les widgets.
    Ceci dit tu peux tout faire avec after()...
    #Rien de nouveau sous le soleil, tout est vanité comme courir après le vent!
    Developpement pour Android avec Python3/Kivy/Buildozer

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Il est dangereux de contrarier une GUI (Tk, Qt, Gtk) par des collisions externes (ici sleep() pour la ralentir). Une GUI possède ce qu'on appelle une "boucle d'évènements" (le truc qui tourne et qui intercepte toutes les actions clavier/souris) et attaquer cette boucle par ces actions système peut provoquer des dysfonctionnements de l'IHM (généralement elle se fige et ne répond plus).

    Une fois entré dans l'IHM, il faut y rester jusqu'à la fin et si tu veux interfacer le système, tu ne dois le faire uniquement que par les outils qu'elle te propose.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre régulier Avatar de scalpel
    Homme Profil pro
    Gestionnaire de parc micro-informatique
    Inscrit en
    Novembre 2008
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Gestionnaire de parc micro-informatique
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2008
    Messages : 148
    Points : 94
    Points
    94
    Par défaut
    Citation Envoyé par MPython Alaplancha Voir le message
    ... La boucle bloque le mainloop ...
    Citation Envoyé par fred1599 Voir le message
    ... L'utilisation de time.sleep() dans une application Tkinter pour introduire des délais peut entraîner des problèmes de performance, notamment le gel de l'interface graphique...
    Citation Envoyé par Sve@r Voir le message
    ... Une fois entré dans l'IHM, il faut y rester jusqu'à la fin et si tu veux interfacer le système, tu ne dois le faire uniquement que par les outils qu'elle te propose.
    Je pense que j'ai bien compris ce vous venez tous les trois de m'expliquer.

    Du coup je vais vous expliquer pourquoi je cherche à ne plus utiliser la méthode after() :

    Comme ma fonction qui déplace le widget est réexécutée une multitude de fois, je ne parviens pas à lui passer les paramètres qui sont sensés évoluer lors du déplacement.
    Par exemple les coordonnées du widget qui sont remises à leurs valeurs indiquées dans le paramètre à chaque exécutions. C'est malheureusement cette même fonction qui est censée faire évoluer les coordonnées. J'utilise donc des variables globales qui me causes d'autres soucis.

    En vous répondant je viens de penser que je peu peut-être récupérer les coordonnées avec un "return" après le déplacement.
    Débutant en janvier 2024 l'apprentissage d'un langage de programmation et n'étant pas particulièrement doué, soyez indulgents.

  6. #6
    Membre régulier Avatar de scalpel
    Homme Profil pro
    Gestionnaire de parc micro-informatique
    Inscrit en
    Novembre 2008
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Gestionnaire de parc micro-informatique
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2008
    Messages : 148
    Points : 94
    Points
    94
    Par défaut
    Mon problème à la base est : Comment passer un paramètre à une fonction qui déplace automatiquement un widget en se réexécutant toute seule et en faisant en sorte que la fonction incrémente elle même ce paramètre à chaque exécutions. Tout ceci sans utiliser de variables globales.
    Débutant en janvier 2024 l'apprentissage d'un langage de programmation et n'étant pas particulièrement doué, soyez indulgents.

  7. #7
    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 scalpel Voir le message
    Du coup ma question finale est : Comment passer un paramètre à une fonction qui déplace un widget en se réexécutant toute seule et en faisant en sorte que se paramètre s'incrémente à chaque exécutions. Tout ceci sans utiliser de variables globales.
    Faire cela c'est associer une fonction à priori sans mémoire à un état (des variables qui traduisent cette mémoire). C'est tout l'intérêt de la méthode d'une instance de classe (qui associe fonction et variables/attributs). Mais en attendant de maîtriser cela difficile de se passer de variables globales (difficile ne veut pas dire impossible mais c'est de la programmation "avancée" pour le plaisir).

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

  8. #8
    Membre expérimenté
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    870
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 870
    Points : 1 522
    Points
    1 522
    Billets dans le blog
    4
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import tkinter as tk
     
    app = tk.Tk()
     
    def move(x, y):
        x += 1
        y += 1
        print(f"x:{x}, y:{y}")    
        app.after(1000, move, x, y)
     
    move(10, 20)
    app.mainloop()
    #Rien de nouveau sous le soleil, tout est vanité comme courir après le vent!
    Developpement pour Android avec Python3/Kivy/Buildozer

  9. #9
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 817
    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 817
    Points : 7 110
    Points
    7 110
    Par défaut
    voici un 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
    import tkinter as tk
     
    def deplacer_widget(x, increment=10):
        # Déplacer le widget horizontalement
        canvas.move(rectangle, increment, 0)
     
        # Incrémentation de la position pour le prochain déplacement
        x += increment
     
        # Planification de la prochaine exécution
        root.after(100, deplacer_widget, x, increment)
     
     
    # Initialisation de la fenêtre principale
    root = tk.Tk()
    root.geometry("600x400")
     
    canvas = tk.Canvas(root, width=600, height=400)
    canvas.pack()
     
    # Création d'un rectangle
    rectangle = canvas.create_rectangle(50, 150, 150, 250, fill="blue")
     
    # Démarrage du déplacement avec la position initiale x = 0
    deplacer_widget(x=0)
     
    root.mainloop()
    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)

  10. #10
    Membre régulier Avatar de scalpel
    Homme Profil pro
    Gestionnaire de parc micro-informatique
    Inscrit en
    Novembre 2008
    Messages
    148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Gestionnaire de parc micro-informatique
    Secteur : Service public

    Informations forums :
    Inscription : Novembre 2008
    Messages : 148
    Points : 94
    Points
    94
    Par défaut
    Citation Envoyé par MPython Alaplancha Voir le message
    ... Ceci dit tu peux tout faire avec after()...
    Je suis un véritable boulet, la réponse d' Alaplancha aurait du me mettre sur la piste.

    Un grand merci pour les exemples, j'avais passé 4 heures sur ce PB avant de questionner.
    Débutant en janvier 2024 l'apprentissage d'un langage de programmation et n'étant pas particulièrement doué, soyez indulgents.

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 01/03/2016, 23h15
  2. [XSLT] Faire une boucle sur une variable [i]
    Par PoT_de_NuTeLLa dans le forum XSL/XSLT/XPATH
    Réponses: 8
    Dernier message: 07/06/2010, 12h45
  3. [directsound] boucle de traitement de son
    Par gargle dans le forum DirectX
    Réponses: 5
    Dernier message: 24/03/2003, 10h47
  4. Sortir d'un progamme qui boucle ou qui refresh
    Par mikevador02 dans le forum C
    Réponses: 12
    Dernier message: 14/12/2002, 09h38
  5. Réponses: 2
    Dernier message: 29/05/2002, 20h43

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