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 :

Tkinter et after


Sujet :

Tkinter Python

  1. #1
    Candidat au Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2012
    Messages : 17
    Points : 4
    Points
    4
    Par défaut Tkinter et after
    Bonjour à tous.
    J'en suis au chapitre 8 du livre de Gérard Swinnen (excellent...) et j'ai fait un petit script pour déplacer quatre balles sur un Canvas et qui fonctionne.
    J'ai utilisé la méthode after, mais même avec la valeur minimum (1 milliseconde) les déplacements sont lents.
    Je me suis aperçu par hasard, en cliquant et en maintenant le clic gauche sur la fenêtre Tkinter pour la changer d'endroit sur l'écran, que le mouvement des balles était considérablement accéléré, et ralentissait dès que je relâchais le bouton de la souris.
    Voilà qui est curieux (pour moi du moins !) : avez- vous une explication ?
    Et peut-on obtenir le même résultat sans cette action sur la souris ?

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

    Le comportement décrit n'étant pas celui "attendu", il vous faudra montrer votre code pour que quelqu'un teste et regarde ce qu'il se passe.

    - W

  3. #3
    Candidat au Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2012
    Messages : 17
    Points : 4
    Points
    4
    Par défaut Tkinter et after
    Bonjour et merci de m'avoir lu.
    Voici le code...
    Fichiers attachés Fichiers attachés

  4. #4
    Candidat au Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2012
    Messages : 17
    Points : 4
    Points
    4
    Par défaut Tkinter et after (envoi du code ?)
    J'ai mis le fichier.py en piece jointe mais apparemment le code n'apparait pas.
    Comment dois-je faire ?

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

    Le but d'une animation est de créer l'illusion d'un déplacement continu alors que les objets se déplacent de façon "discrète" => mettre à jour l'écran de 25 à 50 fois par seconde sera "suffisant" pour faire "illusion"
    Ca donne: 1/25 = 50ms, 1/50 = 20ms.
    Avec 1ms vous allez bouffer du CPU sans que çà n'apporte grand chose.

    Soit DELAY l'intervalle de temps entre les mises à jour.
    Si le déplacement de la balle se fait suivant (dx, dy) "dans cet intervalle", la vitesse est donnée par (dx, dy) / DELAY. Et pour aller "plus vite" il faudra augmenter (dx, dy) - DELAY est maintenant "constant".

    Je me suis aperçu par hasard, en cliquant et en maintenant le clic gauche sur la fenêtre Tkinter pour la changer d'endroit sur l'écran, que le mouvement des balles était considérablement accéléré, et ralentissait dès que je relâchais le bouton de la souris.
    Voilà qui est curieux (pour moi du moins !) : avez- vous une explication ?
    Il ne m'a pas été possible de reproduire cela.
    Désolé.
    - W

  6. #6
    Candidat au Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2012
    Messages : 17
    Points : 4
    Points
    4
    Par défaut Tkinter et after
    Le problème, c'est que si on augmente dx et dy, le mouvement est certes plus rapide, mais aussi moins fluide...
    ( PS: le sens de ma question dans le message précédent était "Que dois-faire ...pour faire apparaitre sur le forum le code de mon script en même temps que le message ? ")

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 347
    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 347
    Points : 36 870
    Points
    36 870
    Par défaut
    Citation Envoyé par plumdoizo Voir le message
    Le problème, c'est que si on augmente dx et dy, le mouvement est certes plus rapide, mais aussi moins fluide...
    ( PS: le sens de ma question dans le message précédent était "Que dois-faire ...pour faire apparaitre sur le forum le code de mon script en même temps que le message ? ")
    La fluidité est la capacité de faire bouger toutes les balles en moins de 1/X secondes.
    Pour faire apparaître le code, vous le coller dans la réponse puis vous l'encadrez de balises [code]
    En cliquant sur le #, çà met les balises autour de la sélection.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if __name__ == '__main__':
         print ('hello')
    - W

  8. #8
    Candidat au Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2012
    Messages : 17
    Points : 4
    Points
    4
    Par défaut Tkinter et after
    Merci pour le conseil pour l'envoi du code (ça risque de me servir assez souvent !...)
    Le voici donc :
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
    from Tkinter import *
     
    def move():
        global listcoordx,listcoordy,bal,listdx,listdy
        dx=int(listdx[bal])
        listcoordx[bal]=int(listcoordx[bal])
        if listcoordx[bal]>380 or listcoordx[bal]<20 :
            dx=-dx
            listdx[bal]=dx
        listcoordx[bal]=listcoordx[bal]+dx
        dy=int(listdy[bal])
        listcoordy[bal]=int(listcoordy[bal])
        if listcoordy[bal]>380 or listcoordy[bal]<20 :
            dy=-dy
            listdy[bal]=dy
        listcoordy[bal]=listcoordy[bal]+dy
        can.coords(listbal[bal],listcoordx[bal]-20,listcoordy[bal]-20,listcoordx[bal]+20,listcoordy[bal]+20)
        bal=bal+1
        if bal==4:
            bal=0
        if flag==1:
            fen.after(1,move)    
     
    def go():
        global flag,b
        if flag==0:
            flag=1
            move()
     
    def stop():
        global flag
        flag=0
    def quit():
        fen.destroy()  
     
    fen=Tk()
    listbal=['b1','b2','b3','b4']
    listcoordx=['50','300','50','300']
    listcoordy=['50','50','300','300']
    listdx=['5','5','5','5']
    listdy=['5','5','5','5']
    listcoul=['red','blue','green','yellow']
    flag,bal=0,0
    can=Canvas(fen,width=400,height=400,bg='dark grey')
    can.grid(row=1,column=1,rowspan=3)
     
    while bal<len(listbal):
        x=int(listcoordx[bal])
        y=int(listcoordy[bal])
        listbal[bal]=can.create_oval(x-20,y-20,x+20,y+20,fill=listcoul[bal])
        bal=bal+1
    bal=0
     
    bout1=Button(text='Go!',command=go)
    bout1.grid(row=1,column=2)
    bout2=Button(text='Stop!',command=stop)
    bout2.grid(row=2,column=2)
    bout3=Button(text='Quitter',command=quit)
    bout3.grid(row=3,column=2)
     
    fen.mainloop()

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 347
    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 347
    Points : 36 870
    Points
    36 870
    Par défaut
    ReSalut,
    Il faut passer du temps sur "fen.after(1,move)".

    Les mises à jour d'une interface graphique telle que Tk se font via la soumission d’événements dans une "event loop". Le fen.after(1,move) fabrique un de ces événements: appeler "move" dans 1ms.

    Le traitement des événements de l'"event loop" se fait de façon séquentielle: tous les événements postés indirectement par move ne seront traités qu'après le retour de "move" (sauf à faire .update_idletasks, ou .update pendant).

    Si on ne laisse pas le temps de "vider" la pile d'événements entre 2 move, çà s'accumule pour rien: les mises à jour n'étant plus faites entre 2 "move".
    => pas facile de contrôler le temps entre 2 move.

    J'ai pris le temps de ré-écrire votre code pour corriger quelques erreurs et montrer un peu ces temps.

    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    import Tkinter as tk
    import time
     
    DEBUG = True
    def debug(s):
        if DEBUG: print(s)
     
    COUNT = 4
    Y_MAX = X_MAX = 400 
    RADIUS = 20
    DELAY = 20
     
    centers = [ (50, 50), (300, 50), (50, 300), (300, 300), ]
    deltas = [ (10, 10) ] * COUNT
    colors = ['red','blue','green','yellow' ]
    idents = [ 0 ] * COUNT
    timer = None
     
    def check_wall_collision(v, du, MIN, MAX):
        dv = du
        if not (MIN <= v <= MAX):
            if v < MIN:
                b = MIN
            else:
                b = MAX
            v = 2 * b - v
            dv = -du
        return v, dv
     
     
    last_move = time.clock()
     
    def move():
        global timer, last_move
        for i in range(COUNT):
            x0, y0 = centers[i]
            dx, dy = deltas[i]
            x1, dx = check_wall_collision(x0 + dx, dx, RADIUS, X_MAX - RADIUS) 
            y1, dy = check_wall_collision(y0 + dy, dy, RADIUS, Y_MAX - RADIUS) 
            assert RADIUS <= x1 <= X_MAX - RADIUS, 'fatal: x1 out of range: (%d, %d)' % (x0, x1)
            assert RADIUS <= y1 <= Y_MAX - RADIUS, 'fatal: y1 out of range: (%d, %d)' % (y0, y1)
            iid = idents[i]
            canvas.move(iid, x1-x0, y1-y0)
            centers[i] = x1, y1
            deltas[i] = dx, dy
        now = time.clock()
        debug('delta: %.3f' % (now - last_move))
        last_move = now    
        timer = app.after(DELAY, move)
     
    def do_start():
        if timer is None:
            move()
     
    def do_stop():
        global timer
        if timer is not None:
            app.after_cancel(timer)
            timer = None
     
    if __name__ == '__main__':
     
        app = tk.Tk()
     
        canvas = tk.Canvas(width=X_MAX,height=Y_MAX,bg='dark grey')
        canvas.grid(row=1,column=1,rowspan=3)
     
        for i in range(COUNT):
            cx, cy = centers[i]
            color = colors[i]
            coords = (cx - RADIUS, cy - RADIUS,
                cx + RADIUS, cy + RADIUS,)
     
            idents[i] = canvas.create_oval(coords, fill=color)
     
        tk.Button(text='Go!',command=do_start).grid(row=1,column=2)
        tk.Button(text='Stop!',command=do_stop).grid(row=2,column=2)
        tk.Button(text='Quitter',command=app.quit).grid(row=3,column=2)
     
        tk.mainloop()
    Jouez avec!
    - W

  10. #10
    Candidat au Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2012
    Messages : 17
    Points : 4
    Points
    4
    Par défaut Tkinter et after
    En effet ça très vite et c'est parfaitement fluide !
    J'ai regardé le code et je crois qu'il me manque quelques notions pour pouvoir "décoder tout le code" ! Comme dit dans mon premier message j'en suis au chapitre 8 de l'ouvrage de Swinnen qui en comporte 19... Mais je ne manquerai pas de revenir à ce script quand j'aurai acquis de nouvelles notions.
    Encore merci ...

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 347
    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 347
    Points : 36 870
    Points
    36 870
    Par défaut
    Citation Envoyé par plumdoizo Voir le message
    En effet ça très vite et c'est parfaitement fluide !
    J'ai regardé le code et je crois qu'il me manque quelques notions pour pouvoir "décoder tout le code" ! Comme dit dans mon premier message j'en suis au chapitre 8 de l'ouvrage de Swinnen qui en comporte 19... Mais je ne manquerai pas de revenir à ce script quand j'aurai acquis de nouvelles notions.
    Encore merci ...
    Arrivé au §8 vous devriez relire pouvoir mon code.
    N'oubliez pas que Swinnen ne s'avale pas comme un polard.
    - W

  12. #12
    Candidat au Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2012
    Messages : 17
    Points : 4
    Points
    4
    Par défaut Tkinter et after
    Bonjour,
    OK, je vais m'y essayer...

Discussions similaires

  1. Droit pour faire un déclencheur "after logon on databas
    Par eXiaNazaire dans le forum Oracle
    Réponses: 5
    Dernier message: 05/01/2005, 15h11
  2. Réponses: 3
    Dernier message: 26/10/2004, 07h31
  3. [Trigger] Trigger instead of , after ?
    Par |DUCATI| DesMo dans le forum Développement
    Réponses: 5
    Dernier message: 05/10/2004, 10h02
  4. Réponses: 3
    Dernier message: 16/08/2004, 10h57
  5. Trigger AFTER
    Par Maitre B dans le forum Développement
    Réponses: 2
    Dernier message: 11/06/2004, 09h56

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