Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsTo receive files in a Tkinter app, install tkinterdnd2, create the window with TkinterDnD.Tk(), register a widget with DND_FILES, and bind <<Drop>>. In the handler, use root.tk.splitlist(event.data) to recover paths safely—including paths containing spaces.
What tkinterdnd2 adds to Tkinter
Tkinter provides Python’s interface to Tcl/Tk, but drag-and-drop support comes from TkDnD, a Tcl/Tk extension. The tkinterdnd2 package wraps that extension and adds methods for registering widgets as drag sources or drop targets and binding drag-and-drop events. See the tkinterdnd2 project documentation and its wrapper API.
As an Amazon Associate I earn from qualifying purchases.
A target must register the kind of data it accepts. For file paths, use DND_FILES (also referred to in the API as DND_Files); for text, use DND_Text. Registering a widget makes it a target, but the application still decides how to process an accepted payload.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Receive dropped files in a Listbox
Install and create the TkDnD root
Install the package in the Python environment used to run your application:
#1 Best Overall
python -m pip install tkinterdnd2
For a standalone Tkinter app, construct the root with TkinterDnD.Tk() rather than tk.Tk(). The following follows the package’s documented Listbox pattern; it has not been independently tested here.
import tkinter as tk
from tkinterdnd2 import DND_FILES, TkinterDnD
root = TkinterDnD.Tk()
items = tk.Listbox(root)
def on_drop(event):
for path in root.tk.splitlist(event.data):
items.insert(tk.END, path)
items.drop_target_register(DND_FILES)
items.dnd_bind("<<Drop>>", on_drop)
items.pack()
root.mainloop()
After the widget is registered and bound, a file drop invokes on_drop; this example adds each path as a separate Listbox entry. Extend the handler to validate the paths or load their contents according to your application’s needs.
Parse the Tcl list; do not split on spaces
event.data is a Tcl list representation, not a simple string with paths separated by spaces. A path containing spaces may be enclosed in braces, so event.data.split() can break one path into several pieces. root.tk.splitlist(event.data) asks Tcl/Tk to parse the list and returns its individual values.
Use another widget as the drop target
The same registration-and-binding interface can make a Canvas a drop target:
canvas.drop_target_register(DND_FILES)
canvas.dnd_bind("<<Drop>>", on_drop)
That accepts a file-list drop at the widget level. If the canvas design needs to place a file on a particular canvas item or use the drop position, implement that behavior in your callback; target registration alone does not decide which item should receive the file. The wrapper API documents widget registration and event binding, but the exact behavior should be checked in the shipped TkDnD and Tcl/Tk environment.
Drag data out of your application
Receiving an external file drop and initiating a drag from one of your own widgets are different operations. To make a widget a source, register it with drag_source_register and bind <<DragInitCmd>>. The initialization callback returns three elements: supported action or actions, data format type or types, and the payload. Drop callbacks return a permitted action such as COPY, MOVE, LINK, ASK, or PRIVATE where the event contract calls for one. Consult the wrapper API for the callback details; a file-drop handler that only receives files is not by itself a drag-source implementation.
Rank #4
Choose the right root integration
Standalone Tkinter window
Use TkinterDnD.Tk() when your application creates and owns its Tk root, as in the Listbox example.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Root owned by another framework
If another GUI framework has already created the Tcl/Tk root, do not create a competing TkDnD root just for drag and drop. The package instructions say to create the existing root first and then call TkinterDnD.require(existing_root) to load the extension into it. See the package instructions for the integration pattern.
Best Value
Package a PyInstaller application
A working development environment does not guarantee the extension’s binaries are included in a bundled executable. The tkinterdnd2 documentation recommends using its hook-tkinterdnd2.py PyInstaller hook so the TkDnD binaries are collected. Follow the package’s current PyInstaller guidance, then verify the generated application on every operating system you intend to ship.
Account for platform and version differences
The wrapper documentation describes TkDnD’s platform mechanisms as XDND version 5 on Unix, OLE2 on Windows, and Cocoa on macOS. These identify underlying mechanisms; they are not a guarantee that every source application, target widget, data format, action, package release, and Tcl/Tk build behaves identically.
The TkDND reference included with the repository has a Unix note saying that dragging from Tk windows had not yet been implemented. That is an older, version-specific statement, not a definitive description of every current tkinterdnd2 build. The PyPI listing accessed October 4, 2026, showed version 0.6.3, uploaded September 4, 2026; package releases and compatibility can change. Check the current package page and test the specific operating system, Tcl/Tk build, source, target, and drag direction you plan to support.
Recommended Free Tools
Quick Recap
Checklist for choosing an implementation
- Receiving files: register a widget with
DND_FILES, bind<<Drop>>, and parse the event withsplitlist. - Receiving text: register the target for
DND_Textand process the text payload in its callback. - Dragging from your app: register a source and provide the action, format, and payload through
<<DragInitCmd>>. - Root ownership: choose
TkinterDnD.Tk()for a standalone app orTkinterDnD.require(root)for an existing framework-owned root. - Deployment: include the TkDnD binaries with the package’s PyInstaller hook and test the built executable on its target platform.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




