crear una imagen en el canvas usando un evento de botón tkinter

Necesito agregar un evento a mis botones en una interfaz gráfica de Tkinter que creará una imagen en el canvas. ¿Cómo lo hago?

Gracias a todos

Funciona pero necesito obtener un número dynamic de imágenes del mismo archivo de imagen, pero cada vez que creo una nueva imagen, la imagen antigua se recolecta como basura. No puedo pensar en qué hacer. Quiero tener múltiples instancias de la misma imagen en mi canvas. Por favor, estaría encantado de algunas sugerencias.

mi código

from Tkinter import * import tkMessageBox def callback(): if tkMessageBox.askokcancel("Quit", "Do you really wish to quit?"): root.destroy() class AppUI(Frame): def __init__(self, master): Frame.__init__(self, master, background="white", relief=FLAT, bd=2, height=768, width=1024) self.menubar = Menu(self) menu = Menu(self.menubar) self.menubar.add_cascade(label="File", menu=menu) menu.add_command(label="New") menu.add_command(label="Open") menu.add_command(label="Save As") menu.add_command(label="Save Copy of") menu.add_separator() menu.add_command(label="exit") menu = Menu(self.menubar) self.menubar.add_cascade(label="Edit", menu=menu) menu.add_command(label="Cut") menu.add_command(label="Copy") menu.add_command(label="Paste") menu = Menu(self.menubar) self.menubar.add_cascade(label="Debug", menu=menu) menu.add_command(label="Open Debugger") menu.add_command(label="Auto-debug") menu.add_command(label="Revert") menu = Menu(self.menubar) self.menubar.add_cascade(label="Run", menu=menu) menu.add_command(label="Stimulation") menu.add_command(label="Check") menu.add_command(label="Scan Module") menu = Menu(self.menubar) self.menubar.add_cascade(label="Help", menu=menu) menu.add_command(label="Help files") menu.add_command(label="FTA site") menu.add_separator() menu.add_command(label="Credits") self.master.config(menu=self.menubar) f0 = Frame(root, background="white") b1 = Button(f0, bd=2, padx=15, pady=15, justify = LEFT) photo1 = PhotoImage(file="Images/p1.gif") b1.config(image = photo1,width="50",height="50", command=self.create_image1) b1.image = photo1 b1.pack(side=LEFT) b2 = Button(f0, bd=2, padx=15, pady=15, justify = LEFT) photo2 = PhotoImage(file="Images/p4.gif") b2.config(image=photo2, width="50",height="50", command = self.create_image2) b2.image = photo2 b2.pack(side=LEFT) b3 = Button(f0,padx=15, bd=2, pady=15, justify = LEFT) photo3 = PhotoImage(file="Images/p8.gif") b3.config(image=photo3, width="50",height="50", command = self.create_image3) b3.image = photo3 b3.pack(side=LEFT) b4 = Button(f0,padx=15, bd=2, pady=15, justify = LEFT) photo4 = PhotoImage(file="Images/p7.gif") b4.config(image=photo4, width="50",height="50", command = self.create_image4) b4.image = photo4 b4.pack(side=LEFT) b5 = Button(f0,padx=15, bd=2, pady=15, justify = LEFT) photo5 = PhotoImage(file="Images/p5.gif") b5.config(image=photo5, width="50",height="50", command=self.create_image5) b5.image = photo5 b5.pack(side=LEFT) f0.pack(anchor=NW, side=TOP) self.canvas = Canvas(self, height=750, width=1500, bg="white") self.canvas.pack(side=LEFT) def create_image1(self): photos1 = PhotoImage(file="Images/p1.gif") self.photos1=photos1 self.img1=self.canvas.create_image(60, 60, image=photos1) self.canvas.bind("", self.move_image1) def create_image2(self): photos2 = PhotoImage(file="Images/p4.gif") self.photos2=photos2 self.img2=self.canvas.create_image(60, 60, image=photos2) self.canvas.bind("", self.move_image2) def create_image3(self): photos3 = PhotoImage(file="Images/p8.gif") self.photos3=photos3 self.img3=self.canvas.create_image(60, 60, image=photos3) self.canvas.bind("", self.move_image3) def create_image4(self): photos4 = PhotoImage(file="Images/p7.gif") self.photos4=photos4 self.img4=self.canvas.create_image(60, 60, image=photos4) self.canvas.bind("", self.move_image4) def create_image5(self): photos5 = PhotoImage(file="Images/p5.gif") self.photos5=photos5 self.img5=self.canvas.create_image(60, 60, image=photos5) self.canvas.bind("", self.move_image5) def move_image1(self, event): self.canvas.delete(self.img1) x = event.x y = event.y self.img1 = self.canvas.create_image(x, y, image=self.photos1, anchor='nw') self.canvas.update() def move_image2(self, event): self.canvas.delete(self.img2) x = event.x y = event.y self.img2 = self.canvas.create_image(x, y, image=self.photos2, anchor='nw') self.canvas.update() def move_image3(self, event): self.canvas.delete(self.img3) x = event.x y = event.y self.img3 = self.canvas.create_image(x, y, image=self.photos3, anchor='nw') self.canvas.update() def move_image4(self, event): self.canvas.delete(self.img4) x = event.x y = event.y self.img4 = self.canvas.create_image(x, y, image=self.photos4, anchor='nw') self.canvas.update() def move_image5(self, event): self.canvas.delete(self.img5) x = event.x y = event.y self.img5 = self.canvas.create_image(x, y, image=self.photos5, anchor='nw') self.canvas.update() root = Tk() root.protocol("WM_DELETE_WINDOW", callback) app = AppUI(root) app.pack() root.mainloop() 

Además, solo la última imagen dibujada se puede arrastrar y soltar. No se puede interactuar con todas las imágenes anteriores. Y, como dije, parece que no puedo crear múltiples imágenes de clones. Sé que debo anclar todas las imágenes para que no se recoja la basura, pero parece que no puedo encontrar una manera de hacerlo. Intenté devolver la instancia de imagen de la función create_image a una matriz. pero no funcionó. Gracias por adelantado

¿Qué problema estás teniendo específicamente? No hay nada complicado al respecto:

 def __init__(...): ... self.canvas = tk.Canvas(...) b = tk.Button(..., command=self.create_image) ... def create_image(self): self.canvas.create_image(...) 

Lo importante a recordar es que las imágenes se recogerán en la basura a menos que guarde una referencia a ellas. Como está creando varias imágenes, una forma fácil de hacerlo es crear una lista a la que puede agregar referencias a las imágenes:

 def __init__(...): ... self.images = [] ... photo1 = PhotoImage(file="Images/p1.gif") self.images.append(photo1) ... 

Hay algunos otros problemas con su código. Por un lado, no es necesario eliminar y luego volver a crear las imágenes cuando se mueven. El canvas tiene un método de move específico para mover elementos existentes. Además, las llamadas a self.canvas.update() son completamente inútiles.

Finalmente, su código será mucho más fácil de mantener si solo tiene un método de “movimiento” en lugar de uno para cada imagen. Eso no es tema para esta pregunta específica, pero es posible que desee buscar lambda y functools.partial como soluciones para poder pasar argumentos a través de enlaces.