【问题标题】:cx_Freeze converted GUI-app (tkinter) crashes after pressing plot buttoncx_Freeze 转换的 GUI 应用程序(tkinter)在按下绘图按钮后崩溃
【发布时间】:2016-04-20 18:52:03
【问题描述】:

我这几天一直在处理这个问题,希望能得到一些帮助。我开发了一个带有导入模块 tkinter、numpy、scipy、matplotlib 的 GUI 应用程序,它在 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 发行版。

【问题讨论】:

  • 想知道这个问题是否与 Windows 10 相关,或者其他 Windows 版本是否也会发生同样的情况。
  • 啊,对不起,我忘了提。在 Windows 7 64 位机器上使用相同的 WinPython 发行版也会出现同样的问题。
  • 刚在32位XP上试过没问题,我以后在64位win7上试试
  • 詹姆斯您好,感谢您提供此信息。很想知道你的 Win 7 系统上会有什么。我也尝试过 Win 8、64 位并遇到同样的问题。
  • 命令提示符中应该有和错误代码弹出。尝试从命令提示符打开exe,这样它就不会立即关闭,让您有时间阅读错误消息。

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


【解决方案1】:

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

我搜索了该文件,发现它位于 numpy 文件夹中。 我将匹配 mkl_*.dlllibiomp5md.dll 的文件复制到 python setup.py build 创建的 test.exe 所在的同一目录中。在此之后,按下 plot 按钮时,最小的 test.exe 会显示 matplotlib 窗口。

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

【讨论】:

  • 这家伙太棒了。我尝试了很多其他的东西,但没有奏效。但这甚至适用于我更复杂的 GUI 和绘图。哇,非常感谢!!!
  • 我正在使用 Anaconda,DLL 不在 lib/site-packages/numpy/code 文件夹中。相反,我在 Anaconda/Library/bin 中找到了它们。
  • 你怎么知道还要使用 libiomp5md.dll 而不是其他任何东西?你能分享一下你的思考过程吗?如果我将来遇到类似的问题,它将对我有所帮助。这个答案对我来说就像魔术一样。我真的不认为它会起作用。我的程序非常复杂。但是您的解决方案很简单!
  • @DirkHaupt 已经有一段时间了,所以我不确定我是否记错了。我使用 Pyinstaller 创建了一个类似的可执行文件,当运行该可执行文件时,会弹出一个对话框告知缺少什么 dll。
  • Windows 10 下的nuitka 和anaconda 也一样
【解决方案2】:

我真的很想发表评论,但我没有声誉。这主要是对 J.J.哈卡拉关于如何找到原因的回答。

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

base = "控制台"

而不是

base = "Win32GUI"

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

英特尔 MKL 致命错误:无法加载 mkl_intel_thread.dll。

这可以帮助更快地找到问题的原因。

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

【讨论】:

    【解决方案3】:

    我已关注@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)
    

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-13
        • 1970-01-01
        相关资源
        最近更新 更多