Tkinter Méthode Delete - Problème avec POO
Laxfiskar
-
Phil_1857 Messages postés 1956 Statut Membre -
Phil_1857 Messages postés 1956 Statut Membre -
Bonjour,
Je commence à appréhender Python et les interfaces graphiques en me forçant à me mettre dans une logique POO.
Dans le but de m'entraîner aux interactions entre classes, j'ai créé ce petit programme très simple, pour faire grossir et diminuer une balle dans un canevas.
Mais par souci d'optimisation, je me doute que la ligne 30 (et 37) n'est pas la plus adaptée. Car s'il y a un autre objet que je souhaitais laisser intact dans le canevas, il serait également effacé. Comment puis-je donc faire pour que l'objet qui appelle la méthode "increase" ou "decrease" s'efface lui-même. En bref par quoi remplacer l'argument "ALL" pour être sélectif sur l'objet concerné?
J'ai tenté de remplacer par self.can.delete(self) mais ça ne fonctionne pas..
J'ai aussi essayé en faisant self.can.delete(self.ball1) mais ça me renvoie une erreur
Je me suis documenté, mais je ne trouve pas de réponse..
Merci beaucoup pour votre aide
Je commence à appréhender Python et les interfaces graphiques en me forçant à me mettre dans une logique POO.
Dans le but de m'entraîner aux interactions entre classes, j'ai créé ce petit programme très simple, pour faire grossir et diminuer une balle dans un canevas.
Mais par souci d'optimisation, je me doute que la ligne 30 (et 37) n'est pas la plus adaptée. Car s'il y a un autre objet que je souhaitais laisser intact dans le canevas, il serait également effacé. Comment puis-je donc faire pour que l'objet qui appelle la méthode "increase" ou "decrease" s'efface lui-même. En bref par quoi remplacer l'argument "ALL" pour être sélectif sur l'objet concerné?
J'ai tenté de remplacer par self.can.delete(self) mais ça ne fonctionne pas..
J'ai aussi essayé en faisant self.can.delete(self.ball1) mais ça me renvoie une erreur
Je me suis documenté, mais je ne trouve pas de réponse..
Merci beaucoup pour votre aide
# Une balle grossit et diminue dans un canevas
class Application(object):
def __init__(self):
"""Constructeur de la fenêtre principale et du canevas"""
self.fen=Tk()
self.can=Canvas(self.fen, width=500, height=500, bg='dark red')
self.can.pack()
self.ball1 = Ball(self.can) # Instanciation d'une balle
self.fen.bind("<Up>",self.ball1.increase)
self.fen.bind("<Down>",self.ball1.decrease)
self.fen.mainloop()
class Ball(object):
"Classe des balles"
def __init__(self, canevas, x=250, y=250, r=10, color='white'):
self.can = canevas
self.x = x
self.y = y
self.r = r
self.fill= color
self.outline= 'black'
self.can.create_oval(x-r,y-r,x+r,y+r,fill=self.fill, outline=self.outline)
def increase(self,event):
"Méthode pour faire grossir la balle avec un appui de touche"
self.r +=10 # La méthode incrémente le rayon
#La méthode doit effacer l'objet existant qui appelle la méthode
self.can.delete(ALL)
#La méthode doit maintenant le recréer
self.can.create_oval(self.x-self.r,self.y-self.r,self.x+self.r,self.y+self.r,fill=self.fill, outline=self.outline)
def decrease(self,event):
"Méthode pour faire diminuer la balle avec un appui de touche"
self.r -=10
self.can.delete(ALL)
self.can.create_oval(self.x-self.r,self.y-self.r,self.x+self.r,self.y+self.r,fill=self.fill, outline=self.outline)
# Programme Principal
if __name__=='__main__':
from tkinter import *
f = Application() # Instanciation de l'objet application
A voir également:
- Tkinter Méthode Delete - Problème avec POO
- Hiberfil.sys delete - Guide
- Just delete me - Guide
- Kismia delete account - Forum Réseaux sociaux
- Méthode lafay pdf - Forum Loisirs / Divertissements
- Methode rar - Guide
6 réponses
Bonsoir Laxfiskar,
Oui, n'efface pas l'objet pour le redessiner, mais met plutôt à jour ses coordonnées
Exemple avec increase:
Il y a déjà moins de lignes de code :-)
Oui, n'efface pas l'objet pour le redessiner, mais met plutôt à jour ses coordonnées
Exemple avec increase:
..........
self.oval = self.can.create_oval(x-r,y-r,x+r,y+r,fill=self.fill, outline=self.outline)
def increase(self,event):
"Méthode pour faire grossir la balle avec un appui de touche"
self.r +=10 # La méthode incrémente le rayon
self.can.coords(self.oval, self.x-self.r,self.y-self.r,self.x+self.r,self.y+self.r)
...................
Il y a déjà moins de lignes de code :-)
Super ça fonctionne!
Si je comprends bien, mon erreur était de ne pas avoir stocké la création du cercle dans une variable. Et donc, impossible d'y faire référence par la suite avec la méthode delete ou coords.
Merci beaucoup pour ton éclairage!
Si je comprends bien, mon erreur était de ne pas avoir stocké la création du cercle dans une variable. Et donc, impossible d'y faire référence par la suite avec la méthode delete ou coords.
Merci beaucoup pour ton éclairage!
C'est parfois utile de donner un nom aux objets que l'on créé
A noter que la méthode coords fonctionne avec toute sorte d'objets ...
Ca aussi peut servir à déplacer la balle, par exemple
A noter que la méthode coords fonctionne avec toute sorte d'objets ...
Ca aussi peut servir à déplacer la balle, par exemple
Merci beaucoup!
J'en profite, car j'ai une deuxième question sur un sujet un peu similaire, mais qui concerne cette fois la méthode AFTER avec Tkinter.
J'essaie tout simplement l'exercice d'animation automatique d'une balle, que je comprends bien en version procédurale, mais ici je coince un peu quand je transforme en version objet.
Le noeud se trouve selon moi à la ligne 41, quand ma fonction anime() doit appeler la fonction after avant de se relancer. (Je souhaite simplement créer une boucle qui s'interrompra plus tard quand la variable flag passera à 0 - partie de code non encore écrite).
Je me rends bien compte que self.fen.after est incorrect car la classe Ball n'a pas de méthode after.. Idem pour self.fen.. Mais comment faire référence à la fenêtre pour que cela fonctionne?
Merci beaucoup pour votre aide
Le code est:
J'en profite, car j'ai une deuxième question sur un sujet un peu similaire, mais qui concerne cette fois la méthode AFTER avec Tkinter.
J'essaie tout simplement l'exercice d'animation automatique d'une balle, que je comprends bien en version procédurale, mais ici je coince un peu quand je transforme en version objet.
Le noeud se trouve selon moi à la ligne 41, quand ma fonction anime() doit appeler la fonction after avant de se relancer. (Je souhaite simplement créer une boucle qui s'interrompra plus tard quand la variable flag passera à 0 - partie de code non encore écrite).
Je me rends bien compte que self.fen.after est incorrect car la classe Ball n'a pas de méthode after.. Idem pour self.fen.. Mais comment faire référence à la fenêtre pour que cela fonctionne?
Merci beaucoup pour votre aide
Le code est:
# Code pour créer une balle animée dans le canevas
class Application(object):
"Classe de création de l'application"
def __init__(self):
#Création de la fenêtre
self.fen = Tk()
self.fen.title('Jeu de la balle')
#Création du canevas
self.can=Canvas(height=500, width=500, bg='aliceblue')
self.can.pack()
#Instanciation d'un objet de la classe Ball
ball1=Ball(self.can, 200, 200, 30, 'lightskyblue')
#Mise en mouvement de la balle
ball1.anime()
# Mise en alerte de la fenetre
self.fen.mainloop()
class Ball(object):
"Classe de création d'une balle"
def __init__(self, canevas, x=100, y=100, r=20, color='white'):
self.can = canevas
self.x = x
self.y = y
self.r = r
self.color = color
self.flag = 1
self.oval = self.can.create_oval(self.x-self.r,self.y-self.r,self.x+self.r,self.y+self.r,fill=self.color)
def anime(self):
self.x += 5
print(self.x)
self.y += 5
self.can.coords(self.oval,self.x-self.r,self.y-self.r,self.x+self.r,self.y+self.r)
if self.flag==1:
self.fen.after(100,ball1.anime)
self.anime()
#----PROGRAMME PRINCIPAL-----
if __name__=='__main__':
from tkinter import *
f=Application()
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
J'ai trouvé la cause.. Je ne passais pas self.fen en paramètre au moment de l'instanciation de l'objet ball1. Donc cet objet ne pouvait pas être appelé.
Voici mon auto-correction:
Voici mon auto-correction:
# Code pour créer une balle animée dans le canevas
# Attention, il faut bien passer la fenetre en parametres!
class Application(object):
"Classe de création de l'application"
def __init__(self):
#Création de la fenêtre
self.fen = Tk()
self.fen.title('Jeu de la balle')
#Création du canevas
self.can=Canvas(height=500, width=500, bg='aliceblue')
self.can.pack()
#Instanciation d'un objet de la classe Ball
ball1=Ball(self.fen, self.can, 200, 200, 30, 'lightskyblue')
#Mise en mouvement de la balle
ball1.anime()
# Mise en alerte de la fenetre
self.fen.mainloop()
class Ball(object):
"Classe de création d'une balle"
def __init__(self, fenetre, canevas, x=100, y=100, r=20, color='white'):
self.fen = fenetre
self.can = canevas
self.x = x
self.y = y
self.r = r
self.color = color
self.flag = 1
self.oval = self.can.create_oval(self.x-self.r,self.y-self.r,self.x+self.r,self.y+self.r,fill=self.color)
def anime(self):
self.x += 5
print(self.x)
self.y += 5
self.can.coords(self.oval,self.x-self.r,self.y-self.r,self.x+self.r,self.y+self.r)
if self.flag >0:
self.fen.after(10,self.anime)
#----PROGRAMME PRINCIPAL-----
if __name__=='__main__':
from tkinter import *
f=Application()