使用mayavi import

时间:2018-05-14 19:08:03

标签: python pyqt data-visualization pyinstaller mayavi

我有一个程序可以通过绘制表面和点云来帮助可视化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安装的。

问题是,如果我使用/ import mayavi模块,我似乎无法获得工作exe。我已经阅读了很多关于不同钩子文件和隐藏导入的github文档,每次我修复一个错误,另一个弹出。这一切都始于scipy,但我相信我已经解决了这些问题。所以我有几个问题可以帮助我解决问题:

1)是否有人使用带有mayavi导入的pyinstaller成功创建了一个独立的exe(具体为from mayavi import mlab)?你的秘密是什么?!?

这看起来很相似,但我还没弄清楚...... SO_link

我使用了以下链接(scipyh5pypandastraits/qt4ETS_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个函数调用中嵌入了一个异常,并且似乎很难找到出错的地方,特别是当谷歌上没有任何东西出现时似乎是相关的。

修改

虽然我仍然很困惑,但我能够改变错误发生的位置。在回溯之后,我在traitsui / editors / code_editor.py(第49行)中注释掉了一条设置标记颜色的线,此时异常随后在下次调用Color方法时开始...但我仍然得到相同的结果RuntimeError。所以这并没有告诉我除了我还在寻找什么隐藏的导入我需要包含这个东西才能工作。

另请注意,我在使用PyInstaller和cx_Freeze时都会遇到完全相同的错误,如果有帮助...

修改2

我现在尝试使用anaconda for python 2.7,相同的问题.....我开始相信宇宙不希望这种情况发生。还有其他地方我应该提起这个问题吗?我已经发布了traitsui GitHub,但这不是很有帮助。这似乎比pyinstaller / cx_freeze更大,因为它发生在两个....

1 个答案:

答案 0 :(得分: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之前