python - objects - tkinter tutorial pdf
La aplicación GUI convertida cx_Freeze(tkinter) se bloquea después de presionar el botón de trazado (4)
He estado lidiando con esto durante días y espero encontrar ayuda. Desarrollé una aplicación GUI con módulos importados tkinter, numpy, scipy, matplotlib, que funciona bien en Python. Después de haber convertido a un exe, todo funciona como se esperaba, pero NO la sección matplotlib. Cuando presiono mi botón de trazado definido, el exe simplemente se cierra y no muestra ningún gráfico. Así que pensé en hacer un ejemplo mínimo, donde simplemente trazo una función pecado y me enfrento al mismo problema: funciona perfectamente en python, al convertirlo en un exe se bloquea al presionar el botón de trazar. Aquí está el ejemplo mínimo:
import tkinter as tk
import matplotlib.pyplot as plt
import numpy as np
class MainWindow(tk.Frame):
def __init__(self):
tk.Frame.__init__(self,bg=''#9C9C9C'',relief="flat", bd=10)
self.place(width=x,height=y)
self.create_widgets()
def function(self):
datax = np.arange(-50,50,0.1)
datay = np.sin(datax)
plt.plot(datax,datay)
plt.show()
def create_widgets(self):
plot = tk.Button(self, text=''PLOT'', command=self.function)
plot.pack()
x,y=120,300
root=tk.Tk()
root.geometry(str(x)+"x"+str(y))
app = MainWindow()
app.mainloop()
Y aquí está mi correspondiente
setup.py
para convertir con cx_Freeze:
import cx_Freeze
import matplotlib
import sys
import numpy
import tkinter
base = None
if sys.platform == "win32":
base = "Win32GUI"
executables = [cx_Freeze.Executable("test.py", base=base)]
build_exe_options = {"includes": ["matplotlib.backends.backend_tkagg","matplotlib.pyplot",
"tkinter.filedialog","numpy"],
"include_files":[(matplotlib.get_data_path(), "mpl-data")],
"excludes":[],
}
cx_Freeze.setup(
name = "test it",
options = {"build_exe": build_exe_options},
version = "1.0",
description = "I test it",
executables = executables)
Cualquier idea que pueda resolver el problema es muy apreciada. Estoy trabajando en una máquina Windows10 de 64 bits y estoy usando la distribución WinPython con Python 3.4.3.
Compruebe si tiene instalado el paquete numpy + mkl. Desinstalar numpy e instalar numpy + mkl package resolvió mi problema de obtener un error relacionado con mkl_intel_thread.dll
Encontré una posible solución (o al menos una explicación) para este problema al probar PyInstaller con el mismo test.py. Recibí un mensaje de error sobre la falta de un archivo dll, ese archivo es mkl_intel_thread.dll .
Busqué ese archivo y lo encontré dentro de la carpeta
numpy
.
Copié archivos que coinciden con
mkl _ *.
Dll
y también
libiomp5md.dll
en el mismo directorio donde estaba el
test.exe
creado por la
python setup.py build
.
Después de esto, el
test.exe
mínimo mostró la ventana matplotlib al presionar el botón de
trazado
.
Los archivos se ubicaron en la carpeta lib / site-packages / numpy / core .
He seguido la respuesta de @JJ Hakala , pero descubrí que no es necesario copiar todos los archivos mkl _ *. Dll y libiomp5md.dll. Para mí funcionó con libiomp5md.dll mkl_core.dll mkl_def.dll mkl_intel_thread.dll. Esto ayuda a reducir el tamaño final del paquete en ~ 500 MB.
Además, puede incluir los archivos que desea copiar en la opción
include_files
.
También es posible que solo desee incluirlos si
sys.platform
es
win32
.
Estoy usando Anaconda y @Matt Williams , así que, cambiando un poco el código del OP:
import cx_Freeze
import matplotlib
import sys
import numpy
import tkinter
import os
PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))
build_exe_options = {"includes": ["matplotlib.backends.backend_tkagg","matplotlib.pyplot",
"tkinter.filedialog","numpy"],
"include_files":[(matplotlib.get_data_path(), "mpl-data")],
"excludes":[],
}
base = None
if sys.platform == "win32":
base = "Win32GUI"
DLLS_FOLDER = os.path.join(PYTHON_INSTALL_DIR, ''Library'', ''bin'')
dependencies = [''libiomp5md.dll'', ''mkl_core.dll'', ''mkl_def.dll'', ''mkl_intel_thread.dll'']
for dependency in dependencies:
build_exe_options[''include_files''].append(os.path.join(DLLS_FOLDER, dependency))
executables = [cx_Freeze.Executable("test.py", base=base)]
cx_Freeze.setup(
name = "test it",
options = {"build_exe": build_exe_options},
version = "1.0",
description = "I test it",
executables = executables)
Realmente quería publicar esto como un comentario, pero no tengo la reputación. Esto es principalmente un seguimiento de la respuesta de JJ Hakala sobre cómo encontrar la causa.
Si uno cambia la base a "Consola", es decir, usando
base = "Console"
más bien que
base = "Win32GUI"
también aparecerá una consola cuando se inicie el programa y se imprima este error
Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll.
Lo que puede ayudar a encontrar la causa del problema bastante más rápido.
Pensé que esto valdría la pena mencionar, ya que este truco también puede ser útil para diagnosticar otros problemas. En la versión final, uno puede volver a Win32GUI para evitar la consola adicional. Debería dar los créditos a esta otra publicación de