问题
I need to load multiple scenes with option to switch them. Something like on the image:
For button "1" something like mlab.points3d(x1, y1, z1, s1, color=blue)
For button "2" something like mlab.points3d(x2, y2, z2, s2, color=red)
For button "3" something like mlab.points3d(x3, y3, z3, s3, color=green)
How to manage drawing inside another scene? (I suppose that mlab.points3d
should be done before option to switch between scenes).
And how to define buttons for scheme switching?
回答1:
Here is an example of how to embed a mayavi plot within pyqt with several buttons. It is based on the Qt embedding example from the mayavi website. If you want to write a relatively large application I would advise you to move the code that is now at the bottom under the if main == "main" line into several seperate classes.
from pyface.qt import QtGui, QtCore
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.clf()
self.scene.mlab.test_points3d()
def second_plot(self):
self.scene.mlab.clf()
from numpy import sin, cos, mgrid, pi, sqrt
u, v = mgrid[- 0.035:pi:0.01, - 0.035:pi:0.01]
X = 2 / 3. * (cos(u) * cos(2 * v)
+ sqrt(2) * sin(u) * cos(v)) * cos(u) / (sqrt(2) -
sin(2 * u) * sin(3 * v))
Y = 2 / 3. * (cos(u) * sin(2 * v) -
sqrt(2) * sin(u) * sin(v)) * cos(u) / (sqrt(2)
- sin(2 * u) * sin(3 * v))
Z = -sqrt(2) * cos(u) * cos(u) / (sqrt(2) - sin(2 * u) * sin(3 * v))
S = sin(u)
self.scene.mlab.mesh(X, Y, Z, scalars=S, colormap='YlGnBu', )
def third_plot(self):
self.scene.mlab.clf()
self.scene.mlab.test_plot3d()
# 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()
# 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()
mayavi_widget = MayaviQWidget(container)
container.setWindowTitle("Embedding Mayavi in a PyQt4 Application")
# define a "complex" layout to test the behaviour
layout = QtGui.QHBoxLayout(container)
button_container = QtGui.QWidget()
button_layout = QtGui.QVBoxLayout(button_container)
button1 = QtGui.QPushButton('1')
button1.clicked.connect(mayavi_widget.visualization.update_plot)
button_layout.addWidget(button1)
button2 = QtGui.QPushButton('2')
button2.clicked.connect(mayavi_widget.visualization.second_plot)
button_layout.addWidget(button2)
button3 = QtGui.QPushButton('3')
button3.clicked.connect(mayavi_widget.visualization.third_plot)
button_layout.addWidget(button3)
layout.addWidget(button_container)
button_container.show()
layout.addWidget(mayavi_widget)
container.show()
window = QtGui.QMainWindow()
window.setCentralWidget(container)
window.show()
# Start the main event loop.
app.exec_()
来源:https://stackoverflow.com/questions/50467139/mayavi-multiple-scene-selector