How to Implement Drag and Drop Functionality in Python Tkinter?

In this tutorial, I will explain how to implement a drag and drop functionality in Python Tkinter. As a developer working on a project for a client, I recently needed to add drag and drop support to a Tkinter application. After researching different approaches, I discovered some simple techniques that made the process much simpler than expected. I’ll walk through the key steps and provide suitable examples.

Implement Drag and Drop Functionality in Python Tkinter

In Tkinter, you can implement drag and drop (DnD) functionality using mouse events (<ButtonPress>, <B1-Motion>, <ButtonRelease>).

import tkinter as tk

def on_drag_start(event):
    """Stores the widget and initial position when dragging starts."""
    event.widget.startX = event.x
    event.widget.startY = event.y

def on_drag_motion(event):
    """Moves the widget to the new position while dragging."""
    x = event.widget.winfo_x() + (event.x - event.widget.startX)
    y = event.widget.winfo_y() + (event.y - event.widget.startY)
    event.widget.place(x=x, y=y)

# Create main window
root = tk.Tk()
root.geometry("500x400")
root.title("Drag and Drop Example")

# Create draggable label
label = tk.Label(root, text="Drag Me!", bg="lightblue", font=("Arial", 14))
label.place(x=50, y=50)  # Initial position

# Bind events for drag & drop
label.bind("<ButtonPress-1>", on_drag_start)
label.bind("<B1-Motion>", on_drag_motion)

root.mainloop()

You can see the output in the screenshot below.

Implement Drag and Drop Functionality in Python Tkinter

on_drag_start(event) → Stores the initial click position.on_drag_motion(event) → Calculates new position & moves the widget.label.bind("<ButtonPress-1>", on_drag_start) → Detects mouse press.label.bind("<B1-Motion>", on_drag_motion) → Moves label dynamically.

Read How to Create a Date Time Picker using Python Tkinter?

Example 1: Drag & Drop Multiple Widgets

This allows multiple widgets (labels & buttons) to be dragged.

import tkinter as tk

def on_drag_start(event):
    """Stores the widget and initial click position."""
    event.widget.startX = event.x
    event.widget.startY = event.y

def on_drag_motion(event):
    """Moves the widget dynamically while dragging."""
    x = event.widget.winfo_x() + (event.x - event.widget.startX)
    y = event.widget.winfo_y() + (event.y - event.widget.startY)
    event.widget.place(x=x, y=y)

# Create main window
root = tk.Tk()
root.geometry("500x400")
root.title("Multi-Widget Drag and Drop")

# Create draggable widgets
widgets = [
    tk.Label(root, text="Drag Label 1", bg="lightgreen"),
    tk.Label(root, text="Drag Label 2", bg="lightcoral"),
    tk.Button(root, text="Drag Button 1"),
    tk.Button(root, text="Drag Button 2"),
]

# Position widgets randomly
positions = [(50, 50), (200, 50), (50, 150), (200, 150)]
for widget, pos in zip(widgets, positions):
    widget.place(x=pos[0], y=pos[1])
    widget.bind("<ButtonPress-1>", on_drag_start)
    widget.bind("<B1-Motion>", on_drag_motion)

root.mainloop()

You can see the output in the screenshot below.

How to Implement Drag and Drop Functionality in Python Tkinter

Allows multiple widgets to be draggable. It uses a list of widgets and loops through them to bind events. Each widget is placed at different positions.

Check out How to Display Data in Textboxes using Python Tkinter?

Example 2: Drag & Drop Inside a Canvas

Using a Canvas is a better approach when dealing with images or shapes.

import tkinter as tk

def on_drag_start(event):
    """Captures the item ID when dragging starts."""
    canvas.tag_raise(event.widget)  # Bring item to front
    event.widget.startX = event.x
    event.widget.startY = event.y

def on_drag_motion(event):
    """Moves the item on the canvas while dragging."""
    dx = event.x - event.widget.startX
    dy = event.y - event.widget.startY
    canvas.move(event.widget, dx, dy)
    event.widget.startX = event.x
    event.widget.startY = event.y

# Create main window
root = tk.Tk()
root.geometry("500x400")
root.title("Canvas Drag and Drop")

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

# Create draggable rectangles
rect1 = canvas.create_rectangle(50, 50, 150, 150, fill="blue", tags="draggable")
rect2 = canvas.create_rectangle(200, 50, 300, 150, fill="red", tags="draggable")

# Bind drag events to all draggable objects
for item in canvas.find_withtag("draggable"):
    canvas.tag_bind(item, "<ButtonPress-1>", on_drag_start)
    canvas.tag_bind(item, "<B1-Motion>", on_drag_motion)

root.mainloop()

You can see the output in the screenshot below.

Implement Drag and Drop Functionality in Python Tkinter canvas

Uses Canvas to draw shapes.Uses canvas.create_rectangle() to create draggable rectangles.Uses canvas.move() to adjust positions dynamically.

Read How to Set a Background Image in Python Tkinter?

Example 3: Drag & Drop Files

This example lets you drag files from Windows Explorer and drop them into the Tkinter window.

import tkinter as tk
from tkinterdnd2 import DND_FILES, TkinterDnD

def drop_file(event):
    """Handles the dropped file path."""
    file_path = event.data  # File path as a string
    label.config(text=f"Dropped file:\n{file_path}")

# Create a special TkinterDnD window
root = TkinterDnD.Tk()
root.geometry("500x300")
root.title("File Drag and Drop")

label = tk.Label(root, text="Drag & Drop a file here", bg="lightgray", width=50, height=10)
label.pack(pady=50)

# Enable drop events
label.drop_target_register(DND_FILES)
label.dnd_bind("<<Drop>>", drop_file)

root.mainloop()

Uses tkinterdnd2 (must be installed: pip install tkinterdnd2).Registers the label as a drop target.Updates the label with the file path when a file is dropped.

Check out How to Create Window Titles in Python Tkinter?

Conclusion

In this tutorial, I have explained how to drag and drop functionality in Python Tkinter. I discussed some examples of drag and drop multiple widgets, drag and drop inside a canvas, and drag and drop files.

You may like to read:

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.