按下plot-Button后,cx_freeze转换的GUI-app(tkinter)崩溃

时间:2016-01-15 08:06:13

标签: python python-3.x matplotlib tkinter cx-freeze

我几天来一直在处理这个问题,并希望得到一些帮助。我开发了一个带有导入模块的GUI应用程序tkinter,numpy,scipy,matplotlib,它在python本身运行良好。转换为* .exe后,一切都按预期工作,但不是matplotlib部分。当我按下我定义的情节按钮时,* .exe只会关闭,并且不会显示任何情节。 所以我想做一个简约的例子,我只是绘制一个sin函数,我面对同样的问题: 在python中工作得很完美,当将它转换为* .exe时,它会在按下情节按钮时崩溃。简约的例子在这里:

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

并查看相应的" setup.py"用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)

任何可能解决问题的想法都受到高度赞赏。我正在使用64位Windows10计算机,而且我正在使用带有Python 3.4.3的WinPython发行版。

4 个答案:

答案 0 :(得分:26)

我在使用相同的 test.py 测试PyInstaller时发现了这个问题的潜在解决方案(或至少是一个解释)。我收到有关dll文件丢失的错误消息,该文件为 mkl_intel_thread.dll

我搜索了该文件,它在 numpy 文件夹中找到。 我将与 mkl _ * .dll 以及 libiomp5md.dll 匹配的文件复制到python setup.py build创建的 test.exe 所在的目录中是。在此之后,当按情节按钮时,最小的 test.exe 显示了matplotlib窗口。

文件位于 lib \ site-packages \ numpy \ core 文件夹中。

答案 1 :(得分:5)

我真的很想发表评论,但我没有声誉。这主要是J.J.的后续行动。 Hakala关于如何找到原因的答案。

如果将基数更改为“控制台”,即使用

base = "Console"

而不是

base = "Win32GUI"

程序启动时也会弹出控制台并打印出此错误

Intel MKL FATAL ERROR: Cannot load mkl_intel_thread.dll.

这有助于更快地找到问题的原因。

我认为这值得一提,因为这个技巧也有助于诊断其他问题。在最终版本中,可以恢复到Win32GUI以避免额外的控制台。我应该将这些学分给予其他stackoverflow post

答案 2 :(得分:2)

我已经遵循@J.J. Hakala的回答,但是我发现没有必要复制所有mkl _ *。dll和libiomp5md.dll文件。对我来说,它使用libiomp5md.dll mkl_core.dll mkl_def.dll mkl_intel_thread.dll。这有助于将最终捆绑包的大小减小到约500MB。

此外,您可以在include_files选项中包含要复制的文件。如果sys.platformwin32,您也只想包含它们。

我正在使用Anaconda和@Matt Williams,因此,请更改一下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)

答案 3 :(得分:0)

检查是否已安装numpy + mkl软件包。卸载numpy并安装numpy + mkl软件包解决了我遇到与mkl_intel_thread.dll相关的错误的问题