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.

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.

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.

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:
- How to Create an OptionMenu in Python Tkinter?
- How to Create Responsive Layouts with Python Tkinter’s Grid Geometry Manager?
- How to Master the Python Tkinter Mainloop?

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.