How to move a Tkinter canvas with Mouse?

Tkinter Canvas widget is one of the versatile widgets in the Tkinter library. It is used to create different shapes, images, and animating objects. We can move images in a particular direction on the Canvas widget using the move() method.

Define the image and the coordinates as a parameter in the move(Image, x, y) method to move the object in the Canvas. We declare images globally in order to move or change the position.

We can follow these steps to allow our image to move within the canvas:

  • First, define the Canvas widget and add images to it.

  • Define the move() function to allow the image to be dynamic within the Canvas.

  • Bind the mouse buttons with the function that allows images to be moved within the Canvas.

Method 1: Moving Canvas Objects with Mouse Click and Drag

This approach creates a new image at each mouse position during dragging ?

# Import the required libraries
from tkinter import *
from PIL import Image, ImageTk

# Create an instance of tkinter frame
win = Tk()

# Set the size of the tkinter window
win.geometry("700x350")

# Define a Canvas widget
canvas = Canvas(win, width=600, height=400, bg="white")
canvas.pack(pady=20)

# Add Images to Canvas widget
image = ImageTk.PhotoImage(Image.open('logo.png'))
img = canvas.create_image(250, 120, anchor=NW, image=image)

def left(e):
    x = -20
    y = 0
    canvas.move(img, x, y)

def right(e):
    x = 20
    y = 0
    canvas.move(img, x, y)

def up(e):
    x = 0
    y = -20
    canvas.move(img, x, y)

def down(e):
    x = 0
    y = 20
    canvas.move(img, x, y)

# Define a function to allow the image to move within the canvas
def move(e):
    global image
    image = ImageTk.PhotoImage(Image.open('logo.png'))
    img = canvas.create_image(e.x, e.y, image=image)

# Bind the move function
canvas.bind("<B1-Motion>", move)

win.mainloop()

Method 2: Better Approach Using Canvas Item Movement

A more efficient approach that moves the same object instead of creating multiple images ?

import tkinter as tk

# Create main window
root = tk.Tk()
root.title("Move Canvas Object with Mouse")
root.geometry("600x400")

# Create canvas
canvas = tk.Canvas(root, width=500, height=300, bg="lightblue")
canvas.pack(pady=20)

# Create a rectangle that we can move
rect = canvas.create_rectangle(50, 50, 100, 100, fill="red", outline="black")

# Variables to store mouse position
start_x = 0
start_y = 0

def on_click(event):
    global start_x, start_y
    start_x = event.x
    start_y = event.y

def on_drag(event):
    global start_x, start_y
    # Calculate how far the mouse moved
    dx = event.x - start_x
    dy = event.y - start_y
    
    # Move the rectangle
    canvas.move(rect, dx, dy)
    
    # Update start position for next movement
    start_x = event.x
    start_y = event.y

# Bind mouse events
canvas.bind("<Button-1>", on_click)
canvas.bind("<B1-Motion>", on_drag)

root.mainloop()
A window opens with a red rectangle that can be dragged around the canvas with the mouse.

Method 3: Moving Multiple Objects

You can also move multiple objects by detecting which item is clicked ?

import tkinter as tk

root = tk.Tk()
root.title("Move Multiple Canvas Objects")
root.geometry("600x400")

canvas = tk.Canvas(root, width=500, height=300, bg="white")
canvas.pack(pady=20)

# Create multiple objects
circle = canvas.create_oval(50, 50, 100, 100, fill="blue")
square = canvas.create_rectangle(150, 50, 200, 100, fill="green")
triangle = canvas.create_polygon(250, 50, 275, 100, 225, 100, fill="yellow")

# Variables for drag operation
selected_item = None
start_x = 0
start_y = 0

def on_click(event):
    global selected_item, start_x, start_y
    # Find the item under the mouse cursor
    selected_item = canvas.find_closest(event.x, event.y)[0]
    start_x = event.x
    start_y = event.y

def on_drag(event):
    global selected_item, start_x, start_y
    if selected_item:
        dx = event.x - start_x
        dy = event.y - start_y
        canvas.move(selected_item, dx, dy)
        start_x = event.x
        start_y = event.y

def on_release(event):
    global selected_item
    selected_item = None

# Bind events
canvas.bind("<Button-1>", on_click)
canvas.bind("<B1-Motion>", on_drag)
canvas.bind("<ButtonRelease-1>", on_release)

root.mainloop()
A window with three shapes (circle, square, triangle) that can each be individually dragged.

Key Points

  • <Button-1> - Left mouse button click event

  • <B1-Motion> - Mouse movement while left button is held down

  • <ButtonRelease-1> - Left mouse button release event

  • canvas.move(item, dx, dy) - Moves item by dx and dy pixels

  • canvas.find_closest(x, y) - Finds the canvas item closest to coordinates

Comparison

Method Performance Use Case
Creating new images Poor Not recommended
Moving existing item Good Single object movement
Multiple object selection Good Interactive applications

Conclusion

Use canvas.move() to efficiently move existing canvas items rather than creating new ones. Bind mouse events like <Button-1> and <B1-Motion> to enable drag-and-drop functionality for interactive canvas applications.

Updated on: 2026-03-25T23:24:39+05:30

6K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements