I’ve spent some time to search for workable solution to do Drag and Drop behavior with Python Tkinter on OSX platform, and the most possible solution found is TkDnD library.
http://sourceforge.net/projects/tkdnd/files/
However I cannot find any manual or guide about the installation and basically no sample on OSX. Can anyone share their experience with me?
Furthermore, is it not a good choice to use Tkinter as a GUI solution? My users are all OSX platform and Python is preinstalled on all these machines. Any good suggestion to find a native GUI support without additional installation? PyQT seems to be another choice, but not sure if it requires the additional installation on Client machine.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
I got this working on both Windows (10) and OSX (10.11) by downloading:
A) Tk extensions tkdnd2.8 from https://sourceforge.net/projects/tkdnd/
B) Python wrapper TkinterDnD2 from https://sourceforge.net/projects/tkinterdnd/
On OSX:
1) Copy the tkdnd2.8 directory to /Library/Tcl
2) Copy the TkinterDnD2 directory to /Library/Frameworks/Python.framework/Versions/…/lib/python/site-packages
(Use the sudo command for copying files on OSX due to permissions.)
On Windows:
1) Copy the tkdnd2.8 directory to …Pythontcl
2) Copy the TkinterDnD2 directory to …PythonLibsite-packages
And here’s a simple test case based on python drag and drop explorer files to tkinter entry widget. The TkinterDnD2 download comes with much more robust examples.
import sys
if sys.version_info[0] == 2:
from Tkinter import *
else:
from tkinter import *
from TkinterDnD2 import *
def drop(event):
entry_sv.set(event.data)
root = TkinterDnD.Tk()
entry_sv = StringVar()
entry_sv.set('Drop Here...')
entry = Entry(root, textvar=entry_sv, width=80)
entry.pack(fill=X, padx=10, pady=10)
entry.drop_target_register(DND_FILES)
entry.dnd_bind('<<Drop>>', drop)
root.mainloop()
Update: the above procedure works for Python 2 or 3.
Method 2
This is an update from 2017, with a bit more detail, since Mac decided to make it impossible to write files to /System/Library. The following solution is also cross-platform, since I am currently writing an app for both Windows/Mac that uses TkDnD.
The following solution works with pyInstaller, and also with Mac OS 10.12 and Windows 7.
First, we need to get a path to where tkDnD is. By default, I place tkdnd2.8 folder next to main.py.
import sys, os
if getattr(sys, 'frozen', False):
# If the application is run as a bundle, the pyInstaller bootloader
# extends the sys module by a flag frozen=True and sets the app
# path into variable _MEIPASS'.
application_path = sys._MEIPASS
else:
application_path = os.path.dirname(os.path.abspath(__file__))
TK_DND_PATH = os.path.join(application_path,'tkdnd2.8')
Note that Ellis’s solution works Tcl directly, modifying the path. Make sure that SOMEWHERE, you have something along this gist:
import tkinter as tk
root = tk.Tk()
root.eval('lappend auto_path {' + TK_DND_PATH + '}')
After this, whenever you happen to actually import tkDnD, it will find it. I used DnD.py. Without the ‘lappend auto_path’ command, my program could never find tkDnD.
https://mail.python.org/pipermail/tkinter-discuss/2005-July/000476.html
Method 3
I spent a few days to figured out how to install TkDnD lib, although it sounds like an easy question but did confused me a little while.
Two ways to install TkDnD on OSX:
A. Copy to /System/Library/Tcl/8.x:
OSX preinstalled Python already, and this is the path where Tcl library is installed. TkDnd lib will be loaded automatically while using Tk/Tcl lib.
B. Set os.environ['TKDND_LIBRARY'] to the location of TkDnd2.x.dylib:
Sample code:
if sys.platform == 'win32':
if getattr(sys, 'frozen', False):
os.environ['TKDND_LIBRARY'] = os.path.join(os.path.dirname(sys.executable), 'tkdnd2.7')
Method 4
2021 update
it annoyed me enough,so after the author did not responded I’ve forked the repo and built wheel for the latest compiled release(2.9.2) and upload it to pypi
you can now just do pip install tkinterdnd2 and it should work.
import is tkinterdnd2 and not Tkinterdnd2. see demos
Method 5
This is an update from 2020 for MacOS Catalina users.
Firstly, the tkdnd library project has been moved to github. The latest version is 2.9.3, and if you do not want to compile the library yourself the latest release is 2.9.2.
Secondly, placing the tkdnd lib on /Library/Tcl doesn’t work anymore (you will get “error: tkdnd library not found”). With Catalina, python looks for the tkdnd lib in its own folder, that is /Library/Frameworks/Python.framework/Versions/…/lib. Placing the tkdnd2.9.3 folder in this path works just fine.
By the way, placing the TkinterDnD2 Python wrapper in /Library/Frameworks/Python.framework/Versions/…/lib/python/site-packages still works on Catalina.
Just to clarify, I only tested it for Python 3 (3.8.5), I do not know if for Python 2 the solution is the same but I suppose so.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0