我正在制作一个 UI,其中涉及将 Mayavi View 嵌入到带有控件的 wx 框架中,但我遇到了一些问题。为了解决这个问题,我整理了一个工作 script这是他们的组合 wx embedding和 red ball picker examples ;我的项目是这个的更复杂的版本。
我有两个问题:
- 如果用户选择了不同数量的球,我想清除图形并用一组新的球重新绘制。但是,根据我从谷歌搜索中收集到的信息,我需要在 clf() 调用后重置选择器。我见过的类似示例将 @on_trait_change 装饰器用于 scene.activated 特征,但我不确定当场景未激活但只是更新时如何执行此操作。
- 如果用户选择不同的球颜色,我想简单地就地更改颜色,而无需重新创建场景。看来我可以通过使用 set method of the glyph's mlab_source 来做到这一点,我认为最好使用 @on_trait_change 来调用它。但是,我不知道如何最好地将 wx 触发事件连接到允许触发 @on_trait_change 的特征类型。
提前致谢。
附言我想把这个贴在 enthought mailing list 上但是该站点似乎已关闭并且已经关闭了一段时间。有人注意到同样的情况吗?
最佳答案
我不确定我是否理解问题所在。为了让您的代码正常工作,在 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
(我已经调整了上面的代码以反射(reflect)这一点)。相反,调用每个源模块的 remove
方法,这将导致源从场景中删除自身:
def clear_figure(self):
for child in self.scene.mayavi_scene.children:
child.remove()
之后,拾取器将断开连接,但您可以创建新对象,然后像往常一样通过调用 on_mouse_pick
将拾取器重新附加到新对象。
关于wxpython - Mayavi:帮助重置鼠标选择器并将 wx 事件连接到@on_trait_change,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23435986/