[ Enhancement ] A potential Drag and Drop solution on tkinter that's in the user code space. No PSG modification needed

Author: PySimpleGUICreated Jun 5, 2026Updated Aug 3, 2026
LabelsenhancementdocumentationDone - Install Dev Build (see docs for how)Demo ProgramsPort - TK

Type of Issue (Enhancement, Error, Bug, Question)

Enhancement


Operating System

Tested on Windows so far

PySimpleGUI Port (tkinter, Qt, Wx, Web)

tkinter


Versions

Python version (sg.sys.version)

Tested on 3.11 & 3.14

PySimpleGUI Version (sg.__version__)

6.1.6

In theory this hack should work with almost any version of PySimpleGUI

GUI Version (tkinter (sg.tclversion_detailed), PySide2, WxPython, Remi)

Tested on 8.6.12 & 8.6.15


Detailed Description

Drag and drop has been something we've wanted on tkinter for some time, but I hadn't found a way to do it that didn't involve pulling more packages/code into PySimpleGUI itself. I might have found a way to do it entirely in the user code space. It looks really sketchy, but does seem to work.

I created a dummy window using the tkinterdnd2 package, hide the window, then created a PySimpleGUI window. After the window is finalized, I registered the Input Element's widget as a drop target and set a callback function.

I opened an issue in the tkinterdnd2 GitHub repo (the one for the matching PyPI package) to see if this a reasonable technique or if I just got lucky in a narrow use case. It would be awesome if it's this simple to add drag and drop to a tkinter PySimpleGUI application. Image Hoping to hear back that it'll work.

Code To Duplicate

python
import PySimpleGUI as sg
from tkinterdnd2 import TkinterDnD, DND_FILES

#----------------------- tkinterdnd2 specific -------------------------------------#

def dnd_init():
    # Make a TkinterDnD dummy window and hide it
    root = TkinterDnD.Tk()
    root.attributes('-alpha', 0)
    root.withdraw()
    dnd_init.root = root

def dnd_exit():
    dnd_init.root.destroy()

def register_element_dnd(element:sg.Element):
    element.widget.drop_target_register(DND_FILES)
    element.widget.dnd_bind("<<Drop>>", on_drop)

#-------------------------PySimpleGUI code ----------------------------------------#


def on_drop(event):
    # Called when a drop event happens
    filepath = event.data.replace("{", "").replace("}", "")    # remove {}  filenames with spaces are in format "{filename with spaces}"
    window["-FILE-"].update(filepath)


dnd_init()

layout = [[sg.Text("Drag & Drop a File Here", key="-DROP-")],
          [sg.Input("", key="-FILE-")],
          [sg.Button("OK"), sg.Button("Cancel")]]

# layout = [[sg.Column(layout, p=0, k='-COL-')]]        # if want to make the entire window the target

window = sg.Window("File Drop", layout, finalize=True)

register_element_dnd(window['-FILE-'])          # register the Input element as the target
# register_element_dnd(window['-COL-'])         # register the column element that contains the entire window as the target

while True:
    event, values = window.read()
    print(event, values)
    if event in (sg.WIN_CLOSED, "Cancel"):
        break

window.close()

dnd_exit()          # being a good citizen and cleaning up the dummy window. May be able to get away with not destroying it

Screenshot, Sketch, or Drawing

Image