'How do I delete trailing objects drawn in tkinter?

My goal is to allow you to make a rectangle on your screen similar to using a rectangle or selection tool in paint. I've got it to mostly work but when you make a rectangle by holding left click and moving your mouse outward and then inward while still holding the button, it leaves behind rectangles that were previously drawn.

Example image

Alternate example when I move my mouse everywhere really fast.

import tkinter as tk
import pyautogui

def draw_rect(event, canvas, pos):
    x, y = pos
    rectangle = canvas.create_rectangle(
        x, y, event.x, event.y, outline="yellow", width=3, fill="blue"
    )


def draw_canvas(event, root, pos):
    canvas = tk.Canvas(root, bg="red")
    canvas.pack(fill=tk.BOTH, expand=True)

    root.bind("<B1-Motion>", lambda event: draw_rect(event, canvas, pos))


Solution 1:[1]

Instead of continuously drawing and deleting rectangles, you should draw a single rectangle and then modify its coordinates as you drag.

Here's a simple example:

import tkinter as tk

root = tk.Tk()
canvas = tk.Canvas(root, bg="black", width=400, height=400)
canvas.pack(fill="both", expand=True)

def draw_drag(event):
    canvas = event.widget
    new_x = canvas.canvasx(event.x)
    new_y = canvas.canvasy(event.y)
    x0, y0, x1, y1 = canvas.coords("current_rect")
    canvas.coords("current_rect", x0, y0, new_x, new_y)

def draw_stop(event):
    canvas.dtag("current_rect")

def draw_start(event):
    canvas = event.widget
    x = canvas.canvasx(event.x)
    y = canvas.canvasy(event.y)
    canvas.create_rectangle(x, y, x, y, fill="red", tags=("current_rect",))


canvas.bind("<ButtonPress-1>", draw_start)
canvas.bind("<ButtonRelease-1>", draw_stop)
canvas.bind("<B1-Motion>", draw_drag)

root.mainloop()


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Bryan Oakley