Mayavi:帮助重置鼠标选择器并将wx事件连接到@on_trait_change

时间:2014-05-02 19:57:48

标签: wxpython enthought mayavi traitsui

我正在创建一个UI,其中涉及在带控件的wx框架中嵌入Mayavi视图,我遇到了一些问题。为了解决这个问题,我整理了一个有效的script,它是wx embeddingred ball picker examples的组合。我的项目是一个更复杂的版本。

我有两个问题:

  1. 如果用户选择不同数量的球,我想清除图形并用一组新球重新绘制。但是,根据我从谷歌搜索中收集到的内容,我需要在clf()调用后重置选择器。我见过的类似例子使用了@on_trait_change装饰器来表示scene.activated特性,但我不确定如何在场景未激活但仅更新场景时这样做。
  2. 如果用户选择不同的球颜色,我只想在不重新创建场景的情况下就地更改颜色。看来我可以使用set method of the glyph's mlab_source来实现,我想最好用@on_trait_change来调用它。但是,我不知道如何最好地将wx触发事件连接到允许触发@on_trait_change的特征类型。
  3. 提前致谢。

    P.S。我希望在enthought mailing list发布此内容,但该网站似乎已关闭且已有一段时间了。有人注意到了吗?

1 个答案:

答案 0 :(得分:2)

我不确定我明白问题所在。为了使代码正常工作,在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将选择器重新附加到新对象。