Problème pour déplacer une image avec tkinter
Résolumomo9213 Messages postés 16 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
J'essaye de crée un aquarium avec des poisson en python, mais je n'arrive pas à faire bouge les poissons malgré mes nombreuses tentatives.
Merci aux personnes qui essayeront de m'aider !
# importation des bibliothèques nécessaires au projet from tkinter import * import tkinter import random # Constantes du projet LARGEUR_F = 800 HAUTEUR_F = 600 # création de la fenêtre de dessin fenetre = tkinter.Tk() mon_canvas = tkinter.Canvas(fenetre, width=LARGEUR_F, height=HAUTEUR_F, background='lightblue') # affichage de la zone de dessin mon_canvas.pack() # stockage de l'image du poisson clown dans une variable img_clown = tkinter.PhotoImage(file="clown_fish.png") img_clown_inv = tkinter.PhotoImage(file="clown_fish_inv.png") # création de la liste des images de poissons liste_images_poissons = [img_clown, img_clown_inv] # classe Poisson class Poisson: # constructeur def __init__(self,xLoc,yLoc,xVel,yVel): self.xLoc = xLoc # entier self.yLoc = yLoc # entier self.xVel = xVel self.yVel = yVel #choix de l'image dans la liste image_choisie =random.choices(liste_images_poissons) # création de l'image dans la zone de dessin self.img = mon_canvas.create_image(self.xLoc,self.yLoc, image=image_choisie) # Accesseurs xLoc et yLoc def getXLoc(self): return self.xLoc def getYLoc(self): return self.yLoc def getXVel(self): return self.xVel def getYVel(self): return self.yVel # Mutateurs xLoc et yLoc def setXLoc(self,x): # x est un float, if 0 <= x <= LARGEUR_F: self.xLoc = x def setYLoc(self,y): # y est un float, if 0 <= y <= HAUTEUR_F: self.yLoc = y def setXVel(self,w): # x est un float, self.xVel = w def setYVel(self,c): # x est un float, self.xVel = c def deplacement(): mon_canvas.move(fish_clown,getlXVel,getYVel) fenetre.after(20,deplacement) class Aquarium: # nom est une chaine de caractere(string), # listeDePoissons est de type list def __init__(self,nom): self.nom=nom self.listeDePoissons=[]# Liste de poissons # Accesseur: def getNom(self): return self.nom # pour ajouter un poisson de classe Poisson def ajouter(self,poisson): self.listeDePoissons.append(poisson) # pour avoir le nombre de poissons de l'aquarium def nbPoissons(self): return len(self.listeDePoissons) mon_aquarium = Aquarium("L'aquarium de FlopMan :|") for i in range(10): temp_xLoc = random.randint(50,750) temp_yLoc = random.randint(50,550) temp_xVel = random.randint(5,10) temp_yVel = random.randint(5,10) mon_aquarium.ajouter(Poisson(temp_xLoc,temp_yLoctemp_yVel,temp_xVel) #instanciation de l'aquarium #mon_aquarium = Aquarium("L'aquarium de FlopMan :|") #ajouts de poissons #mon_aquarium.ajouter(Poisson(400,300)) #mon_aquarium.ajouter(Poisson(700,30)) # gestion des événements, à laisser à la fin du code fenetre.mainloop()
- Problème pour déplacer une image avec tkinter
- Déplacer une colonne excel - Guide
- Image iso - Guide
- Légender une image - Guide
- Déplacer barre des taches windows 11 - Guide
- Reduire taille image - Guide
9 réponses
Bonjour,
Voici ce que je te propose
import tkinter as tk from random import randint WIDTH = 800 HEIGHT = 600 MARGIN = 100 FISH_FILENAME = "/home/toto/poisson.png" NUM_FISHES = 5 FISH_FILENAMES= [FISH_FILENAME] * NUM_FISHES PERIOD = 50 class MoveImageApp(tk.Tk): def __init__(self, period: int = PERIOD, width :int = WIDTH, height :int = HEIGHT, margin :int = MARGIN): super().__init__() self.canvas = tk.Canvas(self, width=width, height=height, background="lightblue") self.canvas.pack() self.period = period self.objs = list() # Could contain tk.PhotoImage, tk.Rectangle, etc. self.photo_images = list() # See https://stackoverflow.com/a/7775792/14851404 self.velocities = list() self.width = width self.height = height self.margin = margin def add_image(self, filename: str, x: int = 0, y: int = 0, vx: int = 0, vy: int = 0): img = tk.PhotoImage(file=filename) x = max(x, self.margin + img.width() / 2) x = min(x, self.width - self.margin - img.width() / 2) y = max(y, self.margin + img.height() / 2) y = min(y, self.height - self.margin - img.width() / 2) self.photo_images.append(img) self.objs.append(self.canvas.create_image(x, y, image=img)) self.canvas.pack() self.velocities.append([vx, vy]) def move_objects(self): for (i, (obj, photo_image, (vx, vy))) in enumerate(zip( self.objs, self.photo_images, self.velocities )): self.canvas.move(obj, vx, vy) (x_min, y_min, x_max, y_max) = self.canvas.bbox(obj) if x_min < self.margin or x_max > self.width - self.margin: self.velocities[i][0] = -self.velocities[i][0] if y_min < self.margin or y_max > self.height - self.margin: self.velocities[i][1] = -self.velocities[i][1] def repeat_move_objects(self): self.move_objects() self.after(self.period, self.repeat_move_objects) app = MoveImageApp(PERIOD, WIDTH, HEIGHT) for filename in FISH_FILENAMES: x = randint(0, app.width) y = randint(0, app.height) vx = randint(-10, 10) vy = randint(-10, 10) app.add_image(filename, x, y, vx, vy) app.after(0, app.repeat_move_objects) app.mainloop()
Le paramètre period détermine le temps (en milliseconde qu'il faut attendre avant de rafraîchir le canvas.
On crée dans notre application un canvas dans lequel on va émuler une marge supérieure, gauche, inférieure et supérieure. Les coordonnées initiales des images insérées doivent à l'intérieure des marges, sans quoi les rebonds des images sur les marges vont faire n'importe quoi.
À chaque mouvement (move_objects), on vérifie qu'on ne fait pas dépasser l'image des marges. On exploite pour celala hit box de l'objet qu'on déplace (voir méthode bbox). Si l'image déborde sur la marge gauche ou droite (resp inférieure ou supérieure), on renverse le vecteur vitesse horizontal (resp. vertical) que j'ai appelé vx (resp. vy). En toute rigueur ce n'est pas vraiment une vitesse (c'est le nombre relatif de pixels dont on déplace l'image), mais l'idée est là.
Bonne chance
bonjour,
à quelle ligne de code fais-tu une tentative de bouger un poisson?
Bonjour,
Certes, tu as défini une fonction deplacement() pour déplacer le poisson, mais tu ne l'appelle jamais, donc
il ne se passe rien ...
La ligne 92 est bancale
"j’a bien essaye de la mettre dans la ligne 92 "
ce n 'est pas la position de la définition de fonction qui importe, ce qu'il faut c'est l'appeler
Exemple d'utilisation de fonction:
def test(): print('hello !') #appel de la fonction: test()
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionEt tu n'as pas de message d'erreur ?
deplacement étant une méthode de la classe Poisson, ce n'est pas comme ça qu'on l'appelle
A mon avis, tu devrais revoir les bases du cours Python sur les classes ...
J’ai essayé de le faire avec des cours sur internet pourriez vous me dire comment faire mieux svp
# importation des bibliothèques nécessaires au projet import tkinter import random from tkinter import * # Constantes du projet LARGEUR_F = 800 HAUTEUR_F = 600 # création de la fenêtre de dessin fenetre = tkinter.Tk() mon_canvas = tkinter.Canvas(fenetre, width=LARGEUR_F, height=HAUTEUR_F, background='lightblue') # affichage de la zone de dessin mon_canvas.pack(padx=10,pady=10) # stockage de l'image du poisson clown dans une variable algue = tkinter.PhotoImage(file="algue.png") tresor = tkinter.PhotoImage(file="tresor.png") img_clown = tkinter.PhotoImage(file="clown_fish.png") img_clown_inv = tkinter.PhotoImage(file="clown_fish_inv.png") img_poisson_orange = tkinter.PhotoImage(file="poisson_orange.png") img_poisson_marron = tkinter.PhotoImage(file="poisson_marron.png") img_poisson_rouge = tkinter.PhotoImage(file="poisson_rouge.png") img_poisson_sarbi = tkinter.PhotoImage(file="poisson_sarbi.png") # création de la liste des images de poissons liste_images_poissons = [img_clown, img_clown_inv,img_poisson_orange,img_poisson_marron,img_poisson_rouge,] # classe Poisson class Poisson: # constructeur def __init__(self,xLoc,yLoc,xVel,yVel): self.xLoc = xLoc # entier self.yLoc = yLoc # entier self.xVel = xVel self.yVel = yVel #choix de l'image dans la liste image_choisie =random.choices(liste_images_poissons) # création de l'image dans la zone de dessin self.img = mon_canvas.create_image(self.xLoc,self.yLoc, image=image_choisie) # Accesseurs xLoc et yLoc def getXLoc(self): return self.xLoc def getYLoc(self): return self.yLoc def getXVel(self): return self.xVel def getYVel(self): return self.yVel # Mutateurs xLoc et yLoc def setXLoc(self,x): # x est un float, if 0 <= x <= LARGEUR_F: self.xLoc = x def setYLoc(self,y): # y est un float, if 0 <= y <= HAUTEUR_F: self.yLoc = y def setXVel(self,w): # x est un float, self.xVel = w def setYVel(self,c): # x est un float, self.xVel = c def affiche(self): self.move(self,self.xVel,self.yVel) # move de l'image dans la zone de dessin def deplacement(self,poisson): fenetre.after(20,deplacement) class Aquarium: # nom est une chaine de caractere(string), # listeDePoissons est de type list def __init__(self,nom): self.nom=nom self.listeDePoissons=[]# Liste de poissons # Accesseur: def getNom(self): return self.nom # pour ajouter un poisson de classe Poisson def ajouter(self,poisson): self.listeDePoissons.append(poisson) # pour avoir le nombre de poissons de l'aquarium def nbPoissons(self): return len(self.listeDePoissons) mon_aquarium = Aquarium("aquarium") for i in range(10): temp_xLoc = random.randint(50,750) temp_yLoc = random.randint(50,550) temp_xVel = random.randint(5,10) temp_yVel = random.randint(5,10) mon_aquarium.ajouter(Poisson(temp_xLoc,temp_yLoc,temp_yVel,temp_xVel)) def fonction_principale(): for i in range(mon_aquarium.nbPoissons()): mon_aquaruim.listeDePoissons[i].deplacement() mon_aquarim.listeDePoissons[i].affiche() mon_canvas.after(100,fonction_principale) fonction_principale() # gestion des événements, à laisser à la fin du code fenetre.mainloop()
Je n’arrive pas à faire les exercices
j’ai essayé de faire celui ci avec le coût qu’il y a avec mais c’est pareil
http://tableauxmaths.fr/spip/spip.php?article48
ou alors, tu essaie déjà avec un poisson et sans utiliser de classes:
définition de la fonction deplace()
(la fonction mon_canvas.move() déplace l'objet img avec des valeurs de déplacement en xy, par exemple 10,-10)
création de la fenêtre principale
création du Canvas
stockage d'une image : img = tkinter.PhotoImage(.....)
affichage de img dans le canvas
appel de deplace()
mainloop()
j'ai essaye ceci mais ca ne marche point
# importation des bibliothèques nécessaires au projet import tkinter # Constantes du projet LARGEUR_F = 800 HAUTEUR_F = 600 # création de la fenêtre de dessin fenetre = tkinter.Tk() mon_canvas = tkinter.Canvas(fenetre, width=LARGEUR_F, height=HAUTEUR_F, background='lightblue') # affichage de la zone de dessin mon_canvas.pack(padx=10,pady=10) img_clown = tkinter.PhotoImage(file="clown_fish.png") mon_canvas.create_image(700,550,image=img_clown) def deplacement(): mon_canvas.move(img_clown,10,10) fenetre.after(20,deplacement) # gestion des événements, à laisser à la fin du code deplacement() fenetre.mainloop()
Bonjour, ce que tu dois déplacer, c'est l'image, de plus 20 ms, c'est bien trop rapide pour tester.
img_clown = tkinter.PhotoImage(file="clown_fish.png") id_image_clown = mon_canvas.create_image(700,550,image=img_clown) def deplacement(): mon_canvas.move(id_image_clown, 10, 10) fenetre.after(200, deplacement)
Bonjour,
Déjà, tu places ton image en bas de la fenêtre (700,550), et en plus, tu la déplaces
vers le bas (y positif : 10,10)
Ensuite, ce n'est pas
fenetre.after(200, deplacement)
Mais
mon_canvas.after(200,deplacement)
Et enfin, ce n'est pas img_clown qu'il faut déplacer, c'est l'objet créé par:
img = mon_canvas.create_image(70,55,image=img_clown)
donc
mon_canvas.move(img,100,100)
Merci de votre réponse mais j'ai réussi à résoudre le problème récemment.