Problème de variable qui ne se met pas à jour

Résolu/Fermé
Ketool - 8 mars 2016 à 01:33
Ketool Messages postés 10 Date d'inscription mardi 8 mars 2016 Statut Membre Dernière intervention 11 mars 2016 - 8 mars 2016 à 18:40
Bonjour à tous,

Cela fait maintenant une semaine que je m'initie à la programmation. J'ai choisi Python comme premier langage. Autant dire que je suis plus que débutant !


Un des exercices qui m'est proposé à ce stade est d'écrire un programme faisant apparaître deux cercles dans un canevas qui peuvent être déplacés individuellement à l'aide de boutons. Sous le canevas, le programme doit afficher en permanence la distance séparant les deux cercles.


Je travaille encore avec des variables globales dans certaines fonctions en raison de mon avancement dans le cours suivi.


Bref, le programme fonctionne parfaitement, sauf en ce qui concerne le calcul de la distance qui ne se met pas à jour lorsque je déplace les cercles. J'ai mis en gras et souligné dans le script ci-dessous la variable qui calcule cette distance en pixels.


Je ne comprends pas pourquoi la valeur de cette variable n'évolue pas lors des mouvements alors que ceux-ci engendrent des changements de valeurs des coordonnées enregistrées dans les variables globales utilisées pour le calcul de la distance....


Si quelqu'un pouvait m'éclairer, je lui en serais très reconnaissant. Merci d'avance pour votre aide.



# -*- coding:Utf-8 -*-
# Python 3.5.1
# Writed by Ketool


from tkinter import *
from math import sqrt


# --- Définition des fonctions du gestionnaire d'évenement ---

def avance(hor, ver):
global x1, y1, x2, y2
if var1.get() and var2.get():
x1, y1, x2, y2 = x1+hor, y1+ver, x2+hor, y2+ver
can1.coords(obj1, x1, y1, x1+20, y1+20)
can1.coords(obj2, x2, y2, x2+50, y2+50)
elif var1.get():
x1, y1 = x1+hor, y1+ver
can1.coords(obj1, x1, y1, x1+20, y1+20)
elif var2.get():
x2, y2 = x2+hor, y2+ver
can1.coords(obj2, x2, y2, x2+50, y2+50)

def haut():
avance(0, -10)

def bas():
avance(0, +10)

def gauche():
avance(-10, 0)

def droite():
avance(+10, 0)


# --------------- Programme principal ---------------


# variable utilisées de manière globale

x1, y1, x2, y2 = 30, 30, 540, 540
dist = round(sqrt((x2-x1)**2+(y2-y1)**2), 2)

# Création du widget principal

fen = Tk()
fen.title("Déplacements multiples selon choix utilisateur et calcul de la distance")


# Création des widgets esclaves

can1 = Canvas(fen, width=600, height=600, bg='ivory')
can1.grid(row=1, column=1, rowspan=7)

obj1 = can1.create_oval(x1, y1, x1+20, y1+20, fill='red')
obj2 = can1.create_oval(x2, y2, x2+50, y2+50, fill='yellow')

var1 = IntVar()
coche1 = Checkbutton(text="Rond rouge", variable=var1)
coche1.grid(row=1, column=2)

var2 = IntVar()
coche2 = Checkbutton(text="Rond jaune", variable=var2)
coche2.grid(row=2, column=2)

Button(fen, text='Haut', command=haut).grid(row=3, column=2)
Button(fen, text='Bas', command=bas).grid(row=4, column=2)
Button(fen, text='Gauche', command=gauche).grid(row=5, column=2)
Button(fen, text='droite', command=droite).grid(row=6, column=2)
Button(fen, text='Quitter', command=fen.destroy).grid(row=7, column=2)

Label(fen, text='La distance entre les deux objets est de : ' + str(dist) + ' pixels').grid(row=8, column=1, columnspan=2)

# Démarrage du gestionnaire d'évenements

fen.mainloop()







A voir également:

1 réponse

jisisv Messages postés 3645 Date d'inscription dimanche 18 mars 2001 Statut Modérateur Dernière intervention 15 janvier 2017 934
Modifié par jisisv le 8/03/2016 à 06:10
C'est normal, tu ne mets pas le label à jour. Une possibilité:
# Python 3.5.1
# Writed by Ketool

from tkinter import *
from math import sqrt


def update_distance(x1, y1, x2, y2):
    global infoLabel
    dist = round(sqrt((x2-x1)**2+(y2-y1)**2), 2)
    infoLabel['text'] = 'La distance entre les deux objets est de : %f pixels' % (dist)

def avance(hor, ver):
    global x1, y1, x2, y2
    if var1.get() and var2.get():        
        x1, y1, x2, y2 = x1+hor, y1+ver, x2+hor, y2+ver
        can1.coords(obj1, x1, y1, x1+20, y1+20)
        can1.coords(obj2, x2, y2, x2+50, y2+50)        
    elif var1.get():
        x1, y1 = x1+hor, y1+ver
        can1.coords(obj1, x1, y1, x1+20, y1+20)       
    elif var2.get():
        x2, y2 = x2+hor, y2+ver
        can1.coords(obj2, x2, y2, x2+50, y2+50)   

    update_distance(x1, y1, x2, y2)
    
def haut():
    avance(0, -10)

def bas():
    avance(0, +10)

def gauche():
    avance(-10, 0)

def droite():
    avance(+10, 0)


# --------------- Programme principal ---------------


# variable utilisées de manière globale

x1, y1, x2, y2 = 30, 30, 540, 540

# Création du widget principal

fen = Tk()
fen.title("Déplacements multiples selon choix utilisateur et calcul de la distance")


# Création des widgets esclaves

can1 = Canvas(fen, width=600, height=600, bg='ivory')
can1.grid(row=1, column=1, rowspan=7)

obj1 = can1.create_oval(x1, y1, x1+20, y1+20, fill='red')
obj2 = can1.create_oval(x2, y2, x2+50, y2+50, fill='yellow')

var1 = IntVar()
coche1 = Checkbutton(text="Rond rouge", variable=var1)
coche1.grid(row=1, column=2)

var2 = IntVar()
coche2 = Checkbutton(text="Rond jaune", variable=var2)
coche2.grid(row=2, column=2)

Button(fen, text='Haut', command=haut).grid(row=3, column=2)
Button(fen, text='Bas', command=bas).grid(row=4, column=2)
Button(fen, text='Gauche', command=gauche).grid(row=5, column=2)
Button(fen, text='droite', command=droite).grid(row=6, column=2)
Button(fen, text='Quitter', command=fen.destroy).grid(row=7, column=2)

dist = round(sqrt((x2-x1)**2+(y2-y1)**2), 2)
infoLabel = Label(fen, text='La distance entre les deux objets est de : ' + str(dist) + ' pixels')
infoLabel.grid(row=8, column=1, columnspan=2 )

# Démarrage du gestionnaire d'évenements

fen.mainloop()


Lors des déplacements, on appelle la fonction update_distance qui modifie le membre text de infoLabel.
Il y aurait pas mal de choses à améliorer mais comme tu débutes
Gates gave ^W  sold  you the windows.
GNU gave us the whole house.(Alexandrin)
0
Ketool Messages postés 10 Date d'inscription mardi 8 mars 2016 Statut Membre Dernière intervention 11 mars 2016
8 mars 2016 à 14:27
Merci beaucoup pour cette solution !

Question de bien comprendre, puis-je encore vous demander comment fonctionne le %f dans la ligne ci-dessous ?

Si j'ai bien compris, ça reprend la variable (dist) indiquée en fin de ligne mais c'est surtout l'utilisation du "f" qui m'intrigue ;-)

infoLabel['text'] = 'La distance entre les deux objets est de : %f pixels' % (dist)


Par ailleurs, je constate que la distance est bien arrondie à 2 chiffres après la virgule mais 6 chiffres restent afficher. 652.459278 devient 652.460000. De quoi cela vient-il ?
0
jisisv Messages postés 3645 Date d'inscription dimanche 18 mars 2001 Statut Modérateur Dernière intervention 15 janvier 2017 934
8 mars 2016 à 17:49
>>> print( "%3.2f" % 652.459278 )
652.46
>>> print( "%8.2f" % 652.459278 )
652.46

Ici 3 et 8 donne la largeur minimale pour l'affichage. 2 est la longueur de la partie décimale

Autre exemple:
>>> print( "%12.11f" % 2.4e-3 )
0.00240000000

Les détails se trouvent sur String Formatting Operations
0
Ketool Messages postés 10 Date d'inscription mardi 8 mars 2016 Statut Membre Dernière intervention 11 mars 2016
8 mars 2016 à 18:40
Merci 1000x :)
0