`Bonjour,
J'ai écrit un programme Python de déplacement de bille dans un cadre avec rebondissement sur les bords du cadre. Mon problème c'est quand je lance le programme avec le nombre de bille N>1, seule une seule bille bouge et les autres restent fixent. Quelqu'un peut m'aider?
Voici le programme :
from tkinter import *
from random import *
class bille:
def __init__(self):
self.i=0
self.x=0
self.y=0
self.dx=0
self.dy=0
def deplace(self,balle):
canvas.move(balle[self.i],self.dx,self.dy)
self.x=canvas.coords(balle[self.i])[2]
self.y=canvas.coords(balle[self.i])[3]
bille.mur(self)
tk.after(20,bille.deplace,self,balle)
def mur(self):
if not(20 < self.y < 310):
self.dy=(-1)*self.dy
if not(20 < self.x < 470):
self.dx=(-1)*self.dx
def demarrer():
N=3
cx,cy,tdx,tdy,balle=[1]*N,[1]*N,[1]*N,[1]*N,[1]*N
for l in range(N):
cx[l],cy[l]=randint(30,420),randint(30,250)
tdx[l],tdy[l]=4,4
for i in range(N):
balle[l]=canvas.create_oval(cx[i],cy[i],cx[i]+15,cy[i]+15,fill='white',outline='black')
for i in range(N):
p=bille()
p.i=i
p.x=cx[i]
p.y=cy[i]
p.dx=tdx[i]
p.dy=tdy[i]
p.deplace(balle)
#Programme Principal
tk=Tk()
canvas=Canvas(tk,width = 480, height = 320 , bd=0, bg="yellow")
canvas.pack()
#Creation d'un bouton "Démarrer"
Boutton_Demarrer=Button(tk,text="Démarrer",command=demarrer)
Boutton_Demarrer.pack(side=LEFT)
#Creation d'un bouton "Detruire":
Bouton_Detruire=Button(tk, text ='Quitter', command = tk.destroy)
#Ajouter l'affichage du bouton dans la fenêtre tk:
Bouton_Detruire.pack(side=RIGHT)
#Boucle principale:
tk.mainloop()
# Boucle infinie
Posté par GuieA_7 (site web personnel) . Évalué à 3.
J'ai du mal à croire que ton programme fonctionne même avec une seule bille. Pour cela il faudrait quand tu appuies sur ton bouton démarrer créer les billes, puis te débrouiller pour que dans sa boucle infinie TK appelle une autre fonction toutes les 15 ms par exemple (pour 60 images par seconde) qui elle déplace tes billes et demande un ré-affichage. Là ta fonction demarrer() est juste appelée une fois quand tu cliques sur le bouton…
[^] # Re: Boucle infinie
Posté par foccus . Évalué à 3.
Pourtant ça fonctionne avec une seule bille. Il y a l'instruction tk.after qui rappelle la fonction deplace toutes les 20ms.
[^] # Re: Boucle infinie
Posté par GuieA_7 (site web personnel) . Évalué à 3.
Ah oui en effet je ne l'avais pas vu ; mis à part que je trouve ça globalement moche que after() soit appelée N fois au lieu d'une seule, est-ce que ça ne serait pas là le problème (je précise que je ne connais pas spécialement Tk) ?
# Erreur d'indice ?
Posté par robinson . Évalué à 5.
peut-être ici, une boucle avec i et balle indexée avec l alors que la boucle l est terminée ?
[^] # Re: Erreur d'indice ?
Posté par foccus . Évalué à 2.
Merci !
# Encore un problème : Carbage collector me joue des tours
Posté par foccus . Évalué à -1.
En reprenant le programme ci-dessus, j’ai voulu placer le nombre de billes N en paramètre pouvant être modifié par l’utilisateur ( bouton Entry). Ca marche, sauf que lorsque l’utilisateur change la valeur de N, on obtient un message d’erreur :
*Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/init.py", line 1699, in __call_
return self.func(*args)
File "/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/init.py", line 745, in callit
func(*args)
File "/Users/foccus/Desktop/Python/Code2/tes1.py", line 13, in deplace
self.x=canvas.coords(balle[self.i])[2]
IndexError: list index out of range_
*
Le programme :
``from tkinter import *
from random import *
class bille:
def init(self):
self.i=0
self.x=0
self.y=0
self.dx=0
self.dy=0
def deplace(self,balle):
canvas.move(balle[self.i],self.dx,self.dy)
self.x=canvas.coords(balle[self.i])[2]
self.y=canvas.coords(balle[self.i])[3]
bille.mur(self)
tk.after(20,bille.deplace,self,balle)
def demarrer():def mur(self):
if not(20 < self.y < 310):
self.dy=(-1)*self.dy
if not(20 < self.x < 470):
self.dx=(-1)*self.dx
Programme Principal
tk=Tk()
canvas=Canvas(tk,width = 480, height = 320 , bd=0, bg="yellow")
canvas.pack()
Creation d'un bouton "Démarrer"
Boutton_Demarrer=Button(tk,text="Démarrer",command=demarrer)
Boutton_Demarrer.pack(side=LEFT)
Creation d'un bouton "Detruire":
Bouton_Detruire=Button(tk, text ='Quitter', command = tk.destroy)
Ajouter l'affichage du bouton dans la fenêtre tk:
Bouton_Detruire.pack(side=RIGHT)
Nombre de balles N
entree_N=Entry(tk,width=3)
entree_N.pack()
Boucle principale:
tk.mainloop()`
`
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.