我正在使用Python 3.5,并且能够使用cx_Freeze创建一个可执行文件,但是每当我尝试运行该可执行文件时,它都将运行且没有错误,但是它无法显示任何matplotlib图形。我已经将Tkinter用于我的GUI。我曾尝试将matplotlib后端作为tkinter放置,但数字仍未显示。我无法共享整个代码,因为它太大了。请帮助。
答案 0 :(得分:0)
以下示例是根据matplotlib
示例Embedding In Tk和cx_Freeze
示例Tkinter改编而成的,适用于我的配置(python 3.6,matplotlib
2.2.2 ,numpy
1.14.3 + mkl,cx_Freeze
5.1.1(在Windows 7上)。
主脚本main.py
:
import tkinter
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
import math
root = tkinter.Tk()
root.wm_title("Embedding in Tk")
# Data for plotting
i = range(0, 300)
t = [_i / 100. for _i in i]
s = [2. * math.sin(2. * math.pi * _t) for _t in t]
fig = Figure(figsize=(5, 4), dpi=100)
fig.add_subplot(111).plot(t, s)
canvas = FigureCanvasTkAgg(fig, master=root) # A tk.DrawingArea.
canvas.draw()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)
toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)
def on_key_press(event):
print("you pressed {}".format(event.key))
key_press_handler(event, canvas, toolbar)
canvas.mpl_connect("key_press_event", on_key_press)
def _quit():
root.quit() # stops mainloop
root.destroy() # this is necessary on Windows to prevent Fatal Python Error: PyEval_RestoreThread: NULL tstate
button = tkinter.Button(master=root, text="Quit", command=_quit)
button.pack(side=tkinter.BOTTOM)
tkinter.mainloop()
# If you put root.destroy() here, it will cause an error if the window is closed with the window manager.
设置脚本setup.py
:
import sys
from cx_Freeze import setup, Executable
import os.path
PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6')
options = {
'build_exe': {
'include_files': [
(os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'), os.path.join('lib', 'tk86t.dll')),
(os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'), os.path.join('lib', 'tcl86t.dll'))
],
'packages': ['numpy']
},
}
base = None
if sys.platform == 'win32':
base = 'Win32GUI'
executables = [
Executable('main.py', base=base)
]
setup(name='matplotlib_embedding_in_Tkinter',
version='0.1',
description='Sample cx_Freeze matplotlib embedding in Tkinter script',
options=options,
executables=executables
)
说明:
Tkinter
和cx_Freeze
冻结应用程序,需要在设置脚本中设置TCL和TK库环境变量,并告诉cx_Freeze
包括相应的DLL,请参见KeyError: 'TCL_Library' when I use cx_Freeze。使用cx_Freeze
5.1.1时,此处描述的解决方案需要进行调整,请参见Getting "ImportError: DLL load failed: The specified module could not be found" when using cx_Freeze even with tcl86t.dll and tk86t.dll added in。numpy
是matplotlib
所必需的,即使应用程序本身未明确使用numpy
,它也必须包含在冻结的应用程序中。为了将numpy
包含在冻结了cx_Freeze
的应用程序中,需要在设置脚本的numpy
选项的packages
列表中添加build_exe
,参见Creating cx_Freeze exe with Numpy for Python。