Dibujando en la pantalla: el widget Canvas de Tkinter
Todo lo que necesitas saber para crear dibujos, diagramas, juegos simples y una mini‑aplicación tipo Paint con Tkinter.
¿Qué es el Canvas y para qué se usa?
El Canvas es el único widget de Tkinter que permite dibujar gráficos vectoriales directamente sobre una superficie pixel‑based. Sus principales casos de uso son:
- Juegos 2D sencillos (p. ej., Snake, Pong).
- Diagramas interactivos (flujos, árboles, mapas de sitio).
- Gráficos estadísticos o de ingeniería (barras, líneas, dispersión).
- Herramientas de edición manual, como un paint básico.
Sistema de coordenadas
El origen ((0,0)) está en la esquina superior‑izquierda del Canvas. El eje x crece hacia la derecha y el eje y hacia abajo. Cada unidad corresponde a un pixel, aunque se pueden aplicar transformaciones de escala para coordenadas lógicas.
Ejemplo rápido:
import tkinter as tk root=tk.Tk() root.title("Canvas ejemplo") canvas=tk.Canvas(root,width=300,height=200,bg="white") canvas.pack() canvas.create_line(0,0,100,50) root.mainloop()
Dibujando primitivas básicas
Líneas y polígonos
canvas.create_line(10, 10, 200, 10, fill="#ff5733", width=3)
canvas.create_polygon(50,60, 150,60, 100,120, outline="black", fill="#88c0d0", width=2)
Rectángulos y óvalos
# rectángulo (x1,y1,x2,y2)
canvas.create_rectangle(20, 150, 180, 250, outline="green", fill="#a3be8c", width=2)
# óvalo (encierra un rectángulo)
canvas.create_oval(220, 150, 320, 250, outline="purple", fill="#b48ead", width=2)
Texto e imágenes
Texto
canvas.create_text(150, 300, text="Hola, Canvas!", font=("Helvetica", 16, "bold"), fill="#5e81ac")
Imágenes
Tkinter necesita objetos PhotoImage o PIL.ImageTk.PhotoImage (para PNG/JPG).
from tkinter import PhotoImage
img = PhotoImage(file="icon.png")
canvas.create_image(300, 300, image=img, anchor="center")
# Nota: mantener una referencia a 'img' para evitar que sea recolectado.
Ejemplo práctico: Mini‑Paint con Tkinter
Una aplicación mínima que permite dibujar con el ratón, cambiar color y grosor.
import tkinter as tkfrom tkinter import colorchooserclass SimplePaint(tk.Tk): def __init__(self): super().__init__();self.title("Simple Paint");self.geometry("800x600");self.current_color="#000000";self.brush_size=3 bar=tk.Frame(self,bg="#eceff4");bar.pack(side="top",fill="x") tk.Button(bar,text="Color",command=self.choose_color).pack(side="left",padx=5) tk.Scale(bar,from_=1,to=10,orient="horizontal",command=self.change_size).pack(side="left") self.canvas=tk.Canvas(self,bg="white",cursor="cross");self.canvas.pack(fill="both",expand=True) self.canvas.bind("<Button-1>",self.on_button_press);self.canvas.bind("<B1-Motion>",self.on_move) self.last_x=None;self.last_y=None def choose_color(self): c=colorchooser.askcolor(initialcolor=self.current_color)[1] if c:self.current_color=c def change_size(self,v): self.brush_size=int(v) def on_button_press(self,e): self.last_x=e.x;self.last_y=e.y def on_move(self,e): if self.last_x is not None: self.canvas.create_line(self.last_x,self.last_y,e.x,e.y,fill=self.current_color,width=self.brush_size,capstyle=tk.ROUND,smooth=True) self.last_x=e.x;self.last_y=e.ySimplePaint().mainloop()
Este código muestra los conceptos clave: manejo de eventos (<ButtonPress-1>, <B1-Motion>), uso de create_line con suavizado y cómo conectar una barra de herramientas sencilla.

Canvas vs. alternativas modernas
Tkinter Canvas
- Incluido en la librería estándar de Python (sin dependencias).
- Ideal para prototipos rápidos y herramientas internas.
- Rendimiento suficiente para < 10 000 objetos visibles.
- Limitado a 2D; no soporta aceleración GPU.
Qt (QGraphicsView) / PySide6
- Renderizado con OpenGL opcional → mejor rendimiento en escenas complejas.
- Mayor soporte para objetos interactivos y transformaciones.
- Curva de aprendizaje más alta y dependencia externa.
- Licencia LGPL/Commercial.
Mejores prácticas, rendimiento y troubleshooting
1️⃣ Minimiza la cantidad de objetos
Demasiados ítems (< 20 000) pueden ralentizar la actualización. Usa create_line con varios puntos o dibuja en una PhotoImage cuando necesites trazos continuos masivos.
2️⃣ Mantén referencias a imágenes
Tkinter elimina imágenes sin referencia explícita, provocando blank canvas. Guarda la imagen en una lista o como atributo del widget.
3️⃣ Gestiona eventos correctamente
Evita crear nuevos objetos dentro de <Motion> sin control de frecuencia; usa after_idle o throttling para limitar a ~60 fps.
4️⃣ Seguridad y sandbox
Cuando cargues imágenes de fuentes externas, valida extensiones y tamaños para prevenir Denial‑of‑Service por archivos enormes.
5️⃣ Compatibilidad
Funciona en Windows, macOS y la mayoría de distribuciones Linux con Tk 8.6+. En macOS, habilita --enable-high-dpi para que el canvas se escale correctamente en pantallas Retina.
Conclusión
El widget Canvas de Tkinter sigue siendo una herramienta poderosa y ligera para crear interfaces gráficas interactivas en Python. Conociendo su sistema de coordenadas, los métodos de dibujo y aplicando buenas prácticas, puedes desarrollar desde diagramas simples hasta mini‑juegos y editores de dibujo sin depender de librerías externas.
13 Dibujando en la pantalla: el widget Canvas de Tkinter