75 - Canvas : borrar figuras mediante Ids y Tags

Cuando creamos una figura con los métodos que provee la clase Canvas, el mismo nos retorna un Id (identificador) de dicha figura. Luego podemos hacer referencia a la misma mediante ese Id.

Podemos asociar además a una o más figuras un Tag (marca) y luego borrar todas las figuras que tienen dicho Tag.

Problema:

Confeccionar un programa que cree un objeto de la clase Canvas y luego dibuje una línea, un réctángulo y un óvalo, almacenar el Id de cada dibujo en un atributo.
Crear también 3 cuadrados y definir el parámetro tag con el mismo valor para cada uno de ellos.

Mediante cinco botones permitir: borrar la línea, borrar el rectángulo, borrar el óvalo, borrar todos los cuadrados y borrar todas las figuras contenidas en el objeto Canvas.

La interfaz visual debe ser similar a esta:

Canvas delete tag id

Programa: ejercicio260.py

Ver video

import tkinter as tk
from tkinter import ttk

class Aplicacion:
    def __init__(self):
        self.ventana1=tk.Tk()
        self.crear_botones()
        self.canvas1=tk.Canvas(self.ventana1, width=600, height=400, background="black")
        self.canvas1.grid(column=0, row=1)
        self.linea=self.canvas1.create_line(0, 0, 100,50, fill="white")        
        self.rectangulo=self.canvas1.create_rectangle(150,10, 300,110, fill="white")
        self.ovalo=self.canvas1.create_oval(400,10,500,150, fill="red")        
        self.canvas1.create_rectangle(100,300,150,350,fill="#aaaaaa", tag="cuadrado")
        self.canvas1.create_rectangle(200,300,250,350,fill="#555555", tag="cuadrado")
        self.canvas1.create_rectangle(300,300,350,350,fill="#cccccc", tag="cuadrado")
        self.ventana1.mainloop()
       
    def crear_botones(self):
        self.labelframe1=ttk.LabelFrame(self.ventana1,text="opciones")
        self.labelframe1.grid(column=0, row=0, sticky="w", padx=5, pady=5)
        self.boton1=ttk.Button(self.labelframe1, text="borrar linea", command=self.borrar_linea)
        self.boton1.grid(column=0, row=0, padx=5)
        self.boton2=ttk.Button(self.labelframe1, text="borrar rectángulo", command=self.borrar_rectangulo)
        self.boton2.grid(column=1, row=0, padx=5)
        self.boton3=ttk.Button(self.labelframe1, text="borrar óvalo", command=self.borrar_ovalo)
        self.boton3.grid(column=2, row=0, padx=5)
        self.boton4=ttk.Button(self.labelframe1, text="borrar todos los cuadrados", command=self.borrar_cuadrados)
        self.boton4.grid(column=3, row=0, padx=5)
        self.boton5=ttk.Button(self.labelframe1, text="borrar todos", command=self.borrar_todos)
        self.boton5.grid(column=4, row=0, padx=5)

    def borrar_linea(self):
        self.canvas1.delete(self.linea)

    def borrar_rectangulo(self):
        self.canvas1.delete(self.rectangulo)

    def borrar_ovalo(self):
        self.canvas1.delete(self.ovalo)

    def borrar_cuadrados(self):
        self.canvas1.delete("cuadrado")

    def borrar_todos(self):
        self.canvas1.delete(tk.ALL)

aplicacion1=Aplicacion()

Las tres primeras figuras que creamos almacenamos en atributos de la clase la referencia a las mismas:

        self.linea=self.canvas1.create_line(0, 0, 100,50, fill="white")        
        self.rectangulo=self.canvas1.create_rectangle(150,10, 300,110, fill="white")
        self.ovalo=self.canvas1.create_oval(400,10,500,150, fill="red")        

Los tres cuadrados que creamos definimos el parámetro tag con el string "cuadrado":

        self.canvas1.create_rectangle(100,300,150,350,fill="#aaaaaa", tag="cuadrado")
        self.canvas1.create_rectangle(200,300,250,350,fill="#555555", tag="cuadrado")
        self.canvas1.create_rectangle(300,300,350,350,fill="#cccccc", tag="cuadrado")

El método 'crear_botones' tiene solo el objetivo de crear los 5 botones que necesita la aplicación y los agrupa en un LabelFrame.

Cuando se presiona el botón de borrar la línea se llama al método delete de la clase Canvas pasando el atributo que almacena la referencia a la línea creada:

    def borrar_linea(self):
        self.canvas1.delete(self.linea)

De forma similar se procede a borrar el rectángulo y el óvalo mediante la referencia del Id:

    def borrar_rectangulo(self):
        self.canvas1.delete(self.rectangulo)

    def borrar_ovalo(self):
        self.canvas1.delete(self.ovalo)

Para eliminar todos los cuadrados también llamamos al método delete y le pasamos el string que almacenamos en su tag:

    def borrar_cuadrados(self):
        self.canvas1.delete("cuadrado")

Finalmente para borrar todos las figuras que tiene un control Canvas debemos llamar a delete y pasar la variable ALL que define el módulo tkinter:

    def borrar_todos(self):
        self.canvas1.delete(tk.ALL)

Acotaciones

Cuando trabajamos con el editor Visual Studio Code podemos navegar la referencia de variables, métodos, clases etc. presionando la tecla Control y posicionando la flecha del mouse sobre el identificar:

Navegar variables, metodos, clases en Python con VS Code

Si hacemos clic luego que aparece subrayado se abre el archivo que contiene dicha definición: Navegar variables, metodos, clases en Python con VS Code

Esta posibilidad de navegar el código fuente de los módulos nos puede facilitar entender su funcionamiento. Según lo visto la variable ALL del módulo tkinter almacena la cadena 'all', luego podemos escribir la eliminación de todos los gráficos con la sintaxis:

    def borrar_todos(self):
        self.canvas1.delete('all')