How to Install and Use TkDnD with Python Tkinter on OSX? - python

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.

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 ...\Python\tcl
2) Copy the TkinterDnD2 directory to ...\Python\Lib\site-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.

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

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

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')

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.

Related

Using Python in Grasshopper3D – Solution exception: No module named AppKit

I am using the Mac version of Rhino/Grasshopper.
I am trying to import a module for using Python inside Grasshopper.
When running the script, I receive the following error.
I have AppKit installed. I’ve even tried saving AppKit and PyObjC in a separate directory and using sys.path.append to access it.
Any idea what I am doing wrong or can try?
Code:
import rhinoscriptsyntax as rs
import AppKit
Code:
import rhinoscriptsyntax as rs
my_path = '/Users/author/Desktop/pyobjc'
sys.path.append(my_path)
import AppKit
The IronPython implemented in Rhino 3D will have search paths that are separate from other Python environments you may have installed.
On Rhino for Windows, you would have been able to run EditPythonScript in the Rhino command line to configure these paths via a dialog. Or _EditPythonScript for a strictly command line approach.
But on Rhino for Mac configuring these paths is less straightforward. There is not yet an editor, debugger, or user interface for configuration fully baked in.
There is a work around using the Atom editor that works with Rhino 5.2 WIP 5C41w and later. After installing the rhino-python package for Atom:
Press the control + option + s to open the Rhino Python Search Paths panel.
Add or edit one or more paths. You cannot edit the default system paths, but can add custom search paths and edit these as needed.
Click Save to update
From your Python scripts in Rhino, you should now be able to import AppKit and other packages from the newly specified locations.

Error: no module named gtk.glade

I researched and tried this for two days now and I cannot get gtk to work on Windows 7 with Python 3.4! Whenever I launch my .py file on Python 3.4 with import gtk, I get No module named gtk! I installed pygobject but it did not help. Even gtk3-demo command works in the windows cmd prompt.
I finally got gtk to import (I think) by copying the GTK directory right to C:\Python34\Lib. But now I have a problem with gtk.glade.
Where is this? Where do I copy it from and to where?
You are possibly using an outdated tutorial, see the current Python GTK 3 tutorial for a more up-to-date reference.
In particular, the way to import GTK has changed in GTK3 to:
from gi.repository import Gtk
And instead of libglade, you would use the newer Gtk.Builder class like so:
ui = Gtk.Builder()
ui.add_from_file("my_glade_file.glade")
(you still develop the UI using Glade, it is only how you access it from your program that has changed).

No module named when using PyInstaller

I try to compile a Python project under Windows 7 using PyInstaller. The project works fine, there are no issues, however when I try to compile it the result doesn't work. Though I get no warnings during compilation there are many in the warnmain.txt file in the build directory: warnmain.txt
I don't really understand those warnings, for example "no module named numpy.pi" since numpy.pi is no module but a number. I never tried to import numpy.pi. I did import numpy and matplotlib explicitly. In addition I'm using PyQt4. I thought the error might be related to those libraries.
However I was able to compile a simple script which uses numpy succesfully:
import sys
from PyQt4 import QtGui, QtCore
import numpy as np
class MainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.pb = QtGui.QPushButton(str(np.pi), self)
app = QtGui.QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())
Successfully here means that the created executable file actually showed the desired output. However there is also a warnmain.txt file created which contains exactly the same 'warnings' as the one before. So I guess the fact that compiling my actual project does not give any success is not (or at least not only) related to those warnings. But what else could be the error then? The only output during compilation are 'INFO's and none of the is a negative statement.
I did not specify an additional hook directory but the hooks where down using the default directory as far as I could read from the compile output, e.g. hook-matplotlib was executed. I could not see any hook for numpy neither could I for my small example script but this one worked. I used the following imports in my files (not all in the same but in different ones):
import numpy as np
import matplotlib.pyplot as ppl
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
from PyQt4 import QtGui, QtCore
import json
import sys
import numpy # added this one later
import matplotlib # added this one later
Since PyInstaller does not give any errors/warnings I could not figure out if the problem is related to the libraries or if there is something else to be considered.
Had a similar problem with no module named FileDialog. Discovered that with version 3.2, I could use
pyinstaller --hidden-import FileDialog ...
instead of modifying my main script.
See Listing Hidden Imports documentation
Pyinstaller won't see second level imports. So if you import module A, pyinstaller sees this. But any additional module that is imported in A will not be seen.
There is no need to change anything in your python scripts. You can directly add the missing imports to the spec file.
Just change the following line:
hiddenimports=[],
to
hiddenimports=["Tkinter", "FileDialog"],
If you are getting ModuleNotFoundError: No module named ... errors and you:
call PyInstaller from a directory other than your main script's directory
use relative imports in your script
then your executable can have trouble finding the relative imports.
This can be fixed by:
calling PyInstaller from the same directory as your main script
OR removing any __init__.py files (empty __init__.py files are not required in Python 3.3+)
OR using PyInstaller's paths flag to specify a path to search for imports. E.g. if you are calling PyInstaller from a parent folder to your main script, and your script lives in subfolder, then call PyInstaller as such:
pyinstaller --paths=subfolder subfolder/script.py.
The problem were some runtime dependencies of matplotlib. So the compiling was fine while running the program threw some errors. Because the terminal closed itself immediately I didn't realize that. After redirecting stdout and stderr to a file I could see that I missed the libraries Tkinter and FileDialog. Adding two imports at the top of the main solved this problem.
I was facing the same problem and the following solution worked for me:
I first removed the virtual environment in which I was working.
Reinstalled all the modules using pip (note: this time I did not create any virtual environment).
Then I called the pyinstaller.
The .exe file created thereafter executed smoothly, without any module import error.
I had the same problem with pyinstaller 3.0 and weblib. Importing it in the main didn't help.
Upgrading to 3.1 and deleting all build files helped.
pip install --upgrade pyinstaller
If the matter is that you don't need Tkinter and friends because you are using PyQt4, then it might be best to avoid loading Tkinter etc altogether. Look into /etc/matplotlibrc and change the defaults to PyQt4, see the 'modified' lines below:
#### CONFIGURATION BEGINS HERE
# The default backend; one of GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo
# CocoaAgg MacOSX Qt4Agg Qt5Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG
# Template.
# You can also deploy your own backend outside of matplotlib by
# referring to the module name (which must be in the PYTHONPATH) as
# 'module://my_backend'.
#modified
#backend : TkAgg
backend : Qt4Agg
# If you are using the Qt4Agg backend, you can choose here
# to use the PyQt4 bindings or the newer PySide bindings to
# the underlying Qt4 toolkit.
#modified
#backend.qt4 : PyQt4 # PyQt4 | PySide
backend.qt4 : PyQt4 # PyQt4 | PySide
May not be a good practice but installing pyinstaller in the original environment used in my project (instead of a separate venv) helped resolve ModuleNotFoundError
I had similar problem with PySimpleGUI.
The problem was, pyinstaller was installed in different directory.
SOLUTION (solved for me) : just install pyinstaller in the same directory in which the file is present (that to be converted to exe)
If these solutions don't work, simply deleting and reinstalling pyinstaller can fix this for you (as it did for me just now).
Putting this here for anyone else who might come across this post.
I had the same error. Mine said "ModuleNotFoundError: No module named 'numpy'". I fixed it by typing the following in the cmd:
pip install pyinstaller numpy

Tkinter OpenGL context in Python

I need to create an OpenGL context in Tkinker, for using it with PyOpenGL Python module.
Tkinker doesn't natively support OpenGL context, but I found this page on PyOpenGL docs, explaining how to use a wrapper included in the module for this:
http://pyopengl.sourceforge.net/documentation/context/
I tried to run the provided code but I got a message saying TOGL module was not found.
I downloaded the module from http://togl.sourceforge.net/, but couldn't get it to work.
PS. I did the test on Mac OS X, with Python 3.2, using virtualenv.
PyOpenGL provides Python bindings for the Tk OpenGL widget (Togl) but not Togl itself, that is why you had to download it. Now, to install Togl is easy but there isn't a tool ready to perform the task. Since the Python bindings will use Tcl to load the Togl module, the widget needs to live in one of the directories present in Tcl's auto_path, which is where Tcl looks for loading libraries. What you can do is start a Tcl interpreter, tclsh, and check which are these directories by doing puts $auto_path. In my case I copied the directory lib/Togl2.0 (inside the Togl's .tar.gz) to /opt/local/lib/tcl8.5. You can also extend auto_path to look for other directories, but I'm not covering that here.
Then I tested using Python 2.7 on Mac OSX. Doing import OpenGL.Tk tries to load Togl, too bad it fails. The reason is that Togl comes precompiled for i386, since I built Python as a universal binary all I did was run it as arch -i386 python2.7, and now import OpenGL.Tk works.

Python tcl is not installed properly

I just installed graphics.py for python.
But when I tried to run the following code:
from graphics import *
def main():
win = GraphWin("My Circle", 100, 100)
c = Circle(Point(50,50), 10)
c.draw(win)
win.getMouse() # Pause to view result
win.close() # Close window when done
main()
my interpreter gave me this strange information:
Traceback (most recent call last):
File "F:\CS 101\Python\projects\packer.py", line 8, in <module>
from graphics import *
File "F:\CS 101\Python\lib\site-packages\graphics.py", line 168, in <module>
_root = tk.Tk()
File "F:\CS 101\Python\lib\tkinter\__init__.py", line 1674, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: Can't find a usable init.tcl in the following directories:
{F:\CS 101\Python\tcl\tcl8.5.9} {F:/CS 101/Python/tcl/tcl8.5} {F:/CS 101/Python/lib/tcl8.5} {F:/CS 101/lib/tcl8.5} F:/lib/tcl8.5 {F:/CS 101/library} F:/library F:/tcl8.5.2/library F:/tcl8.5.2/library
F:/CS 101/Python/tcl/tcl8.5/init.tcl: version conflict for package "Tcl": have 8.5.2, need exactly 8.5.9
version conflict for package "Tcl": have 8.5.2, need exactly 8.5.9
while executing
"package require -exact Tcl 8.5.9"
(file "F:/CS 101/Python/tcl/tcl8.5/init.tcl" line 20)
invoked from within
"source {F:/CS 101/Python/tcl/tcl8.5/init.tcl}"
("uplevel" body line 1)
invoked from within
"uplevel #0 [list source $tclfile]"
This probably means that Tcl wasn't installed properly.
What does it mean?
What can I do?
PS: I am using Eclipse (PyDev) for coding.
I sloved by modifying my activate script:
set "TCL_LIBRARY=D:\Program Files (x86)\Python3.5\tcl\tcl8.6"
set "TK_LIBRARY=D:\Program Files (x86)\Python3.5\tcl\tcl8.6"
Regarding what you can do, you can try editing your init.tcl file to read something like package require Tcl 8.5.0-8.6, or if that doesn't work you can try package require -exact Tcl 8.5.2. I also had to edit my tcl\tk8.5\tk.tcl file in the same way, for Tk instead of Tcl.
If editing the file does not work for you, you can download and install the latest Tcl from:
source using the latest version from sourceforge. This will require having an acceptable compiler. For example, see blog.victorjabur.com/2011/06/05/compiling-python-2-7-modules-on-windows-32-and-64-using-msvc-2008-express/ or stackoverflow.com/questions/4218613/building-a-python-module-on-windows-using-ms-compiler.
the latest ActiveState community version. This may be the easiest option if you have permission to install. Seeing that this is for CS 101, your lab administrators might not allow you that permission (whether by policy or technology). Of course, that also probably means this answer comes too late to help with your immediate need.
Regarding what it means, without more information, I can only make conjectures right now. I had the reverse problem; I will tell you about it in hopes that it gives you some insight into what it might mean.
I have 8.5.9 installed, but init.tcl was requiring 8.5.2. I'm guessing my problem was caused by installing ActiveState python, then official python (both 2.7, 64-bit), and/or additional packages I installed later. There is a note at the bottom of this download page regarding Tcl/Tk on MacOS that one could interpret to mean there is room for trouble on the PC as well. ActiveState Python 2.7 includes Tcl/Tk 8.5.9, as documented here. Using 7-zip to open the msi files from ActiveState and Python.org, and grepping for "tcl" and then "require", I can see that the init.tcl in the ActiveState msi specifies package require -exact Tcl 8.5.9.
My guess is that the 8.5.2 requirement came from the regular python install (which is apparently less grepable), or some package I installed later. Running the ActiveState msi in repair mode does not fix the issue, nor does running the Python msi in repair mode.
P.S If this isn't timely, why did I still answer? Crafting a decent answer for you helped me understand my issue better.
I am running PyCharm IDE with Python 2.7.
Inside c:\Python27\tcl\tcl8.5\init.tcl "package require -exact Tcl 8.5.2" change to
package require -exact Tcl 8.5.9
Inside c:\Python27\tcl\tk8.5\tk.tcl "package require -exact Tk 8.5.2" change to:
package require -exact Tcl 8.5.9
This worked for me.
I faced the same problem during my last installation of ns2.35 in ubuntu 11.04.
After I install ns2.35, got message of successful installation of ns. Then I set path in /.bashrc. Then I gave ns command which gave me same error which you got.
The problem is because, ns executable is also at /usr which is conflicting.
Solution:
Go to location root-usr-local-bin by giving following command in terminal
cd /usr/local/bin
There you would find the ns file. We just need to remove it by giving following command
rm ns
Thats it, you are done. Now your ns starts running successfully.
There maybe a compatibility issue with another program that uses the TCL_Library environment variable. In the attached thread I changed the environment variable path and it fixed my issue. It may be relevant to your problem:
Python IDLE won´t start
The PATH solution did't work for me. I'm using Win7 python 2.7.
Finally I edited 2 files:
C:\Python27\tcl\tk8.5\tk.tcl
package require -exact Tk 8.5.2
change into
package require Tk 8.5.0-8.6
C:\Python27\tcl\tcl8.5\init.tcl
package require -exact Tcl 8.5.2
change into
package require Tcl 8.5.0-8.6
And this works! Previously my IDLE never pops out, but now it works as well. Cool, thanks #Jonathan Spooner and #hlongmore
I think I had the very same problem under windows8/python2.7. It was a hell of installations and env variables setting. All of them worthless. Today I've found a solution:
Downloading and installing python at D: (in order to preserve my installation) and then copying the folder Tcl into my C: installation in the same relative position: C:\Python27
To give a more general solution, in the error traceback, you should have something like:
C:/Users/[perso path]/tcl/tcl8.6/init.tcl: version conflict for package "Tcl": have 8.6.6, need exactly 8.6.8
version conflict for package "Tcl": have 8.6.6, need exactly 8.6.8
So just open the file described in the error: C:/Users/[perso path]/tcl/tcl8.6/init.tcl and replace package require -exact Tcl 8.6.8 with the version needed in the error, for me it was 8.6.6: package require -exact Tcl 8.6.6.
Then the same problem will happen with Tk (with another file), I did the same operations and it worked. Maybe you won't have the same versions, just replace them.
I had a similar problem when generating a simple scatter plot using mayplotlib.pyplot in Windows 10. I solved by adding the new environment variables in
Control Panel>System and Security>System>Advanced system settings>Environment Variables>User variables for UserName:
Variable Name: TCL_LIBRARY, Variable value=C:\Python27\tcl\tcl8.5
Variable Name: TK_LIBRARY, Variable value=C:\Python27\tcl\tk8.5

Categories