我不确定我是否理解问题所在。为了让您的代码正常工作,在 wx 通知程序(您有参考)中调用场景并进行必要的调整似乎很简单。像这样:
def on_number_of_balls_selected():
n = self.get_selected_ball_number()
clear_figure()
#mlab.clf(scene = self.mayavi_view.scene.mayavi_scene )
# make some new points
new_points = somehow_make_some_new_points(n)
mlab.points3d( new_points, scene=self.mayavi_view.scene.mayavi_scene )
# reattach the picker
picker = self.mayavi_view.figure.on_mouse_pick(self.mayavi_view.picker_callback)
依此类推,这些调用可能不会完全正确地组合在一起,但这是基本思想。
如果您使用 traitsui,解决方案在概念上没有什么不同,但我很好奇为什么如果您要使用 traitsui 渲染 mayavi 场景,为什么不也使用它来显示 GUI 中的枚举?这确实是 traitsui 的预期用例(对于简单的应用程序)。如果您有理由不这样做 - 太好了,肯定有很多用例,其中 traitsui 不是最好的工具,并且使用工具包(或我个人没有真正尝试过的 enaml)为您提供了更大的控制灵活性布局并提供更广泛的小部件。但是对于这个问题,traitsui 提供了一个更好的解决方案,即在用户更改 GUI 中的某些数字时提供通知(尽管您仍然必须编写侦听器)。
编辑:事实证明,tvtk 选择器会自行分离mlab.clf
(合理)并防止重新连接收听相同事件的新选择器(不太合理)。我相信这是 tvtk 中的一个错误,我无法在 30 分钟内将其隔离。因此,现在我建议完全避免mlab.clf
(我已经调整了上面的代码以反映这一点)。相反,调用remove
每个源模块的方法,这将导致源从场景中删除自己:
def clear_figure(self):
for child in self.scene.mayavi_scene.children:
child.remove()
之后,选择器将断开连接,但您可以创建新对象,然后通过on_mouse_pick
正常调用将选择器重新附加到新对象。