我有一个程序,通过绘制表面和点云来查看它们与表面的关系,从而帮助在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( 有没有人使用带有 mayavi 导入的 pyinstaller 成功创建了一个独立的 exe(特别是from mayavi import mlab
(?你的秘密是什么?!?
这似乎很相似,但我还无法弄清楚......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
我现在已经尝试使用python 2.7的anaconda,同样的问题.....我开始相信宇宙不希望这种情况发生。还有别的地方应该提出这个问题吗?我已经在 traitsui GitHub 上发帖了,但这不是很有帮助。这似乎比pyinstaller/cx_freeze更大,因为它同时发生在两者中。
我处理了同样的问题,最后切换到cx_freeze,它现在在Linux和Windows上运行良好。您正在处理的问题来自 SE 答案中的语句,即动态导入语句,其中导入的内容仅在运行时确定:
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
导入马亚维之前