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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de scalpel
    Homme Profil pro
    Gestionnaire de parc micro-informatique
    Inscrit en
    Novembre 2008
    Messages
    157
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Gard (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Novembre 2008
    Messages : 157
    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 ?

  2. #2
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 082
    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 : 4 082
    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.

  3. #3
    Membre Expert
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    925
    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 : 925
    Billets dans le blog
    8
    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()...

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    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 confirmé Avatar de scalpel
    Homme Profil pro
    Gestionnaire de parc micro-informatique
    Inscrit en
    Novembre 2008
    Messages
    157
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Gard (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Novembre 2008
    Messages : 157
    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.

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

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

    Informations forums :
    Inscription : Novembre 2008
    Messages : 157
    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.

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

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

    Informations forums :
    Inscription : Novembre 2008
    Messages : 157
    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.

  8. #8
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    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 762
    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

  9. #9
    Membre Expert
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    925
    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 : 925
    Billets dans le blog
    8
    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()

  10. #10
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 082
    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 : 4 082
    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()

+ 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