一直以来mayavi只能用pyqt4,但是最近大概是版本更新了吧,直接即可使用。
我使用的是deepin 15.11(一种基于debian的Linux系统,环境类似于Ubuntu)下的anaconda配置环境。前面已经做好了更换清华镜像源等准备。于是最终的代码是:
python 版本为3.6,安装sfepy的原因是要为
conda install sfepy
conda install vtk
conda install mayavi
执行一段时间完成之后,使用pycharm配置python解释器,使用conda interpreter功能,将解释器设置为刚配置好的conda解释器。
然后使用以下代码即可新建界面。
# First, and before importing any Enthought packages, set the ETS_TOOLKIT
# environment variable to qt4, to tell Traits that we will use Qt.
import os
# os.environ['ETS_TOOLKIT'] = 'qt4'
# By default, the PySide binding will be used. If you want the PyQt bindings
# to be used, you need to set the QT_API environment variable to 'pyqt'
os.environ['QT_API'] = 'pyqt5'
# To be able to use PySide or PyQt4 and not run in conflicts with traits,
# we need to import QtGui and QtCore from pyface.qt
from pyface.qt import QtGui, QtCore
# Alternatively, you can bypass this line, but you need to make sure that
# the following lines are executed before the import of PyQT:
# import sip
# sip.setapi('QString', 2)
from traits.api import HasTraits, Instance, on_trait_change
from traitsui.api import View, Item
from mayavi.core.ui.api import MayaviScene, MlabSceneModel, \
SceneEditor
################################################################################
# The actual visualization
class Visualization(HasTraits):
scene = Instance(MlabSceneModel, ())
@on_trait_change('scene.activated')
def update_plot(self):
# This function is called when the view is opened. We don't
# populate the scene when the view is not yet open, as some
# VTK features require a GLContext.
# We can do normal mlab calls on the embedded scene.
# self.scene.mlab.pipeline.surface(self.scene.mlab.pipeline.open("cylinder.vtk"))
self.scene.mlab.test_points3d()
pass
# the layout of the dialog screated
view = View(Item('scene', editor=SceneEditor(scene_class=MayaviScene),
height=250, width=300, show_label=False),
resizable=True # We need this to resize with the parent widget
)
################################################################################
# The QWidget containing the visualization, this is pure PyQt4 code.
class MayaviQWidget(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
layout = QtGui.QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)
self.visualization = Visualization()
# If you want to debug, beware that you need to remove the Qt
# input hook.
# QtCore.pyqtRemoveInputHook()
# import pdb ; pdb.set_trace()
# QtCore.pyqtRestoreInputHook()
# The edit_traits call will generate the widget to embed.
self.ui = self.visualization.edit_traits(parent=self, kind='subpanel').control
layout.addWidget(self.ui)
self.ui.setParent(self)
if __name__ == "__main__":
# Don't create a new QApplication, it would unhook the Events
# set by Traits on the existing QApplication. Simply use the
# '.instance()' method to retrieve the existing one.
app = QtGui.QApplication.instance()
container = QtGui.QWidget()
container.setWindowTitle("Embedding Mayavi in a PyQt5 Application")
# define a "complex" layout to test the behaviour
layout = QtGui.QHBoxLayout(container)
layout.addWidget(QtGui.QLabel("this is a label"))
mayavi_widget = MayaviQWidget()
layout.addWidget(mayavi_widget)
container.show()
window = QtGui.QMainWindow()
window.setCentralWidget(container)
window.show()
app.exec_()
以上代码中,第30行位置上的update_plot()是更新图形的函数。在界面初始化的时候,这个函数会被调用一次。我打出的代码中调用的是:
self.scene.mlab.test_points3d()
如果要导入外部的文件则将这一行改成这一句:
self.scene.mlab.pipeline.surface(self.scene.mlab.pipeline.open("cylinder.vtk"))
至于调用绘图的方法,大概在78行左右,就是将mayavi看做一个窗口即可。熟悉pyqt的话应该很好上手。