TK Framework doble problema de implementación

Estoy probando la creación de una GUI utilizando el módulo Tkinter. Estaba tratando de agregar una imagen a la GUI usando PIL. Mi código se ve así:

import Tkinter as tk from PIL import Image, ImageTk root = tk.Tk() root.title('background image') imfile = "foo.png" im = Image.open(imfile) im1 = ImageTk.PhotoImage(im) 

Cuando ejecuto este código, se me ocurren algunos errores que llevan a una falla de seguridad.

 objc[5431]: Class TKApplication is implemented in both/Users/sykeoh/anaconda/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. objc[5431]: Class TKMenu is implemented in both /Users/sykeoh/anaconda/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. objc[5431]: Class TKContentView is implemented in both /Users/sykeoh/anaconda/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. objc[5431]: Class TKWindow is implemented in both /Users/sykeoh/anaconda/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. Segmentation fault: 11 

He buscado en línea y parece ser un problema con el framework Tk en mi biblioteca de Sistemas y el otro en la biblioteca de anaconda. Sin embargo, ninguna de las soluciones realmente pareció funcionar. ¿Alguna posible solución o solución?

El problema viene con la ejecución de ImageTk.Photoimage. Si elimino esa línea de código, no hay problemas.

Sé que creé la recompensa, pero me impacienté, decidí investigar y ahora tengo algo que me funcionó. Tengo un ejemplo de Python muy similar al tuyo, que no hace nada más que intentar usar Tkinter para mostrar una imagen pasada en la línea de comandos, así:

 calebhattingh $ python imageview.py a.jpg objc[84696]: Class TKApplication is implemented in both /Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. objc[84696]: Class TKMenu is implemented in both /Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. objc[84696]: Class TKContentView is implemented in both /Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. objc[84696]: Class TKWindow is implemented in both /Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. One of the two will be used. Which one is undefined. Segmentation fault: 11 

Lo que está sucediendo es que el archivo binario , ~/anaconda/envs/py35/lib/python3.5/site-packages/PIL/_imagingtk.so se ha vinculado a un marco, y no a las librerías Tcl / Tk en la env. Puedes ver esto usando otool para ver la configuración de enlace:

 (py35)🎨 ~/anaconda/envs/py35/lib/python3.5/site-packages/PIL calebhattingh $ otool -L _imagingtk.so _imagingtk.so: /System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl (compatibility version 8.5.0, current version 8.5.9) /System/Library/Frameworks/Tk.framework/Versions/8.5/Tk (compatibility version 8.5.0, current version 8.5.9) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0) /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0) 

¿Ves esas dos líneas “marco”? Con la anaconda no queremos eso. Queremos utilizar las bibliotecas en el env. Así que vamos a cambiarlos!

Primero haga una copia de seguridad de su binario (en caso de que quiera revertir):

 $ cp _imagingtk.so _imagingtk.so.bak 

Ahora ejecute esto en la línea de comandos (suponiendo que se encuentre en la misma carpeta que su envname/lib ):

 $ install_name_tool -change "/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk" "@rpath/libtk8.5.dylib" _imagingtk.so $ install_name_tool -change "/System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl" "@rpath/libtcl8.5.dylib" _imagingtk.so 

¿Ves ese bit @rpath allí? Eso significa que cualquiera que encuentre en el camino . Lo que funciona muy bien para la anaconda. El enlace en la biblioteca _imagingtk.so ahora se ve así:

 (py35)🎨 ~/anaconda/envs/py35/lib/python3.5/site-packages/PIL calebhattingh $ otool -L _imagingtk.so _imagingtk.so: @rpath/libtcl8.5.dylib (compatibility version 8.5.0, current version 8.5.9) @rpath/libtk8.5.dylib (compatibility version 8.5.0, current version 8.5.9) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0) /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0) 

Después de esto, su código se ejecutará. Alguien debería tratar de conseguir esto aguas arriba.

Addendum : El enlace Tkinter en la distribución de python, es decir, el env de conda actualmente activo, tiene el siguiente enlace:

 🎨 ~/anaconda/envs/py35/lib/python3.5/lib-dynload calebhattingh $ otool -L _tkinter.cpython-35m-darwin.so _tkinter.cpython-35m-darwin.so: @loader_path/../../libtcl8.5.dylib (compatibility version 8.5.0, current version 8.5.18) @loader_path/../../libtk8.5.dylib (compatibility version 8.5.0, current version 8.5.18) /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.0.0) 

Si lo prefiere, puede usar install_name_tool para usar @loader_path/../../ lugar de lo que usé anteriormente, es decir, @rpath/ . Eso probablemente también funcione, e incluso podría ser mejor.

Intento realizar mi propia investigación de este problema (en mi caso fue un problema con matplotlib)

  • Intento encontrar binarios vinculados con las rutas de la biblioteca System Tcl / Tk
  • Con las bibliotecas encontré el archivo, lo que parece realmente interesante. Tiene el nombre osx-tk.patch y se colocó en ~/anaconda/pkgs/matplotlib-1.5.1-np111py35_0/info/recipe/
  • Encontré osx-tk.patch fonts osx-tk.patch en GitHub

  • Después de leer el parche y la documentación de Conda, finalmente me convencí de la instalación incorrecta del paquete, y recuerdo que usé pip para la instalación de matplotlib.

  • He eliminado el paquete antiguo con pip e instalo uno nuevo con el comando conda install matplotlib

  • ¡Ahora todo comenzó a funcionar a la perfección!

Breve resumen:

Usando el administrador de paquetes pip con el entorno conda, desordené mis dependencias, ya que conda puede usar recetas especiales, ese instalador puntual, cómo instalar el paquete correctamente en el entorno virtual conda

Resumen ultra-breve:

Elimine el paquete por completo con las dependencias e instálelo de nuevo con el administrador de paquetes de conda (utilice el nuevo enlace solo en casos difíciles)

Hice exactamente lo que @cjrh dijo para _imagetk.so , pero en lugar de _tkinter.so en ~/anaconda/lib/python3.5/lib-dynload/ y funcionó muy bien!

 cd ~/anaconda/lib/python3.5/lib-dynload $ install_name_tool -change "/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk" "@rpath/libtk8.5.dylib" _tkinter.so $ install_name_tool -change "/System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl" "@rpath/libtcl8.5.dylib" _tkinter.so