使用带有 mayavi 导入的 pyinstaller 创建独立的 exe
Posted
技术标签:
【中文标题】使用带有 mayavi 导入的 pyinstaller 创建独立的 exe【英文标题】:creating standalone exe using pyinstaller with mayavi import 【发布时间】:2018-05-14 19:08:02 【问题描述】:我有一个程序,它通过绘制表面和点云来帮助以 3D 形式可视化一些数据,以查看它们与表面的关系。对于可视化,我使用了 mayavi,因为它易于设置并且在 3D 中比 matplotlib 做得更好。当我在我的 python 环境中运行该程序并进行漂亮的可视化时,该程序运行良好。但是,我需要将它分发给一些没有 Python 并且不想在每台计算机上安装 python 和所有加载项的人,所以我一直在使用 pyinstaller 创建他们的独立 .exe 文件我开发程序后可以运行。
作为参考,这都是在 Windows 10、Python 3.6、pyqt 4.11.4、pyface 6.0.0、traits 4.6.0、pyinstaller 3.3.1、mayavi 4.5.0+vtk81 上完成的。几乎我使用的每个模块都是使用 pip 安装的。
问题是,如果我使用/导入 mayavi 模块,我似乎无法获得工作的 exe。我已经阅读了很多关于不同钩子文件和隐藏导入的 github 文档,每次我修复一个错误时,都会弹出另一个错误。这一切都是从 scipy 开始的,但我相信我已经解决了这些问题。所以我有几个问题可以帮助我解决问题:
1) 有没有人使用 pyinstaller 和 mayavi 导入(特别是 from mayavi import mlab
)成功地创建了一个独立的 exe?你的秘密是什么?!?
这看起来很相似,但我还没有弄清楚...SO_link
我已使用以下链接 (scipy,h5py,pandas,traits/qt4,ETS_TOOLKIT) 来添加隐藏导入或修复其他问题,但在设置 ETS_TOOLKIT=qt4 后我现在卡住了。在设置它之前,我会收到一个 pyface/traits 错误RuntimeError: No traitsui.toolkits plugin found for toolkit null
,但现在它对 qt4 说的是同样的事情,而不是 null。我安装了qt4所以我不明白...它在pyface/base_toolkit.py的import_toolkit函数中。
2) 在创建 3D 可视化/exe 方面有没有更好的方法?我需要一个 3D 程序,如果点在表面之前或之后,它可以准确地渲染,并且能够交互地旋转/缩放/平移,而且它需要直观。 Mayavi 有非常简单的命令,类似于 matplotlib,但其他的似乎非常复杂,围绕 UI 如何与所有内容进行交互。
3) 我如何解释我得到的所有这些错误代码?他们通常非常神秘地说,某行引发了嵌套在其他 10 个函数调用中的异常,而且似乎很难找出到底哪里出了问题,尤其是当 Google 上没有任何似乎相关的弹出窗口时。
编辑
虽然我仍然很困惑,但我已经能够更改错误发生的位置。在回溯之后,我注释掉了在 traitsui/editors/code_editor.py 中设置标记颜色的行(第 49 行),此时异常在下次调用 Color 方法时开始......但我仍然得到相同运行时错误。所以这并没有告诉我太多,除了我仍在寻找我需要包含哪些隐藏的导入才能让这个东西工作。
另外请注意,我在 PyInstaller 和 cx_Freeze 中遇到完全相同的错误,以防万一……
编辑 2
我现在已经尝试使用 anaconda for python 2.7,完全相同的问题.....我开始相信宇宙不希望这种情况发生。还有其他地方我应该提出这个问题吗?我已经在traitsui GitHub上发布了但这不是很有帮助。这似乎比 pyinstaller/cx_freeze 更大,因为它发生在两者中......
【问题讨论】:
【参考方案1】:我处理了同样的问题,最后切换到 cx_freeze,它现在可以在 linux 和 windows 上正常工作。您正在处理的问题来自SE answer 中的语句,您发现,即动态导入语句,其中导入的内容仅在运行时确定:
be = 'pyface.ui.%s.' % tk
__import__(be + 'init')
我无法在 pyinstaller 中解决这个问题,而在 cx_freeze 中,当您在构建文件中明确添加所需的包时,它可以工作。这是我使用的包列表:
"packages": ["pyface.ui.qt4", "tvtk.vtk_module", "tvtk.pyface.ui.wx", "matplotlib.backends.backend_qt4",'pkg_resources._vendor','pkg_resources.extern','pygments.lexers',
'tvtk.pyface.ui.qt4','pyface.qt','pyface.qt.QtGui','pyface.qt.QtCore','numpy','matplotlib','mayavi']
这是一个完整的构建脚本,适用于 python3.6、cx_freeze 5.0.2、mayavi 4.5.0+vtk71、traits 4.6.0、pyface 5.1.0 和 traitsui 5.1.0。
import os
from cx_Freeze import setup, Executable
import cx_Freeze.hooks
def hack(finder, module):
return
cx_Freeze.hooks.load_matplotlib = hack
import scipy
import matplotlib
scipy_path = os.path.dirname(scipy.__file__) #use this if you are also using scipy in your application
build_exe_options = "packages": ["pyface.ui.qt4", "tvtk.vtk_module", "tvtk.pyface.ui.wx", "matplotlib.backends.backend_qt4",'pygments.lexers',
'tvtk.pyface.ui.qt4','pyface.qt','pyface.qt.QtGui','pyface.qt.QtCore','numpy','matplotlib','mayavi'],
"include_files": [(str(scipy_path), "scipy"), #for scipy
(matplotlib.get_data_path(), "mpl-data"),],
"includes":['PyQt4.QtCore','PyQt4.QtGui','mayavi','PyQt4'],
'excludes':'Tkinter',
"namespace_packages": ['mayavi']
executables = [
Executable('main.py', targetName="main.exe",base = 'Win32GUI',)
]
setup(name='main',
version='1.0',
description='',
options = "build_exe": build_exe_options,
executables=executables,
)
我通过以下方式导入pyface:
os.environ['ETS_TOOLKIT'] = 'qt4'
import imp
try:
imp.find_module('PySide') # test if PySide if available
except ImportError:
os.environ['QT_API'] = 'pyqt' # signal to pyface that PyQt4 should be used
from pyface.qt import QtGui, QtCore
在导入 mayavi 之前
【讨论】:
不幸的是,当我运行我的 exe 时,我仍然遇到同样的错误,即使在使用 cx_freeze 创建它之后也是如此。这让我相信我的 mayavi 安装有问题。我将卸载并重新安装以查看是否可以更改它,但它似乎正在寻找一个不存在的目录(traitsui/toolkits) 嗯,我已经卸载并重新安装了除了 python 本身之外我能想到的所有东西,但我仍然有同样的错误。我发现有些东西看起来好像我没有为特征安装 Qt 后端,但没有说明如何检查或安装它....所以仍在进行中。我要下载 Anaconda 看看是否有帮助,因为我不知所措..... @user2731076 另一件事:os.environ['ETS_TOOLKIT'] = 'qt4' 暗示你想使用 pyside。对于 pyqt4 使用 os.environ['QT_API'] = 'pyqt' 除了其他语句 感谢您的帮助。但是,我使用了您的导入脚本和设置脚本,但错误仍然存在。我读到导入 tkinter 也可能是一个问题,但删除它并没有改变任何东西。我觉得它必须是 pyinstaller/cx_freeze 找到导入模块的方式,但它们并不能很容易地找到它丢失的地方,因为我似乎直接指向它...... @user2731076 如果您的代码在 github 上,我可以查看它并尝试检查您的代码或您的环境是否有问题。 github.com/JannickWeisshaupt/OpenDFT 是一个完整的项目,它使用 mayavi 并有一个适用于 windows 的 cx_freeze 构建脚本。如果你愿意,你可以克隆它并尝试检查它是否在你的机器上工作。以上是关于使用带有 mayavi 导入的 pyinstaller 创建独立的 exe的主要内容,如果未能解决你的问题,请参考以下文章
在 parmap 上使用 pyinstaller 会导致 tkinter matplotlib 导入错误。为啥?