如何在活动窗口中以动态的方式修改 Trait 视图?
- 想设置一个界面,在侦听 Trait 时,界面将在不同的预定义视图对象之间切换。
- 如下示例所示:
class App(Handler):
info = Instance(UIInfo)
view_type = Enum('slider_view', 'spinner_view')
number = Range(1, 10)
message = Str('sawmill')
spinner_view = View(Item('number', editor=RangeEditor(mode='spinner', high=10, low=1)), Item('message'), Item('view_type'))
slider_view = View(Item('number', editor=RangeEditor(mode='slider', high=10, low=1)), Item('message'), Item('view_type'))
@on_trait_change('view_type')
def chg_view_type(self):
self.reconstruct()
def init_info(self, info):
self.info = info
def reconstruct(self):
self.info.ui.dispose()
self.info.object.edit_traits(view=self.view_type)
- 使用上述代码确实可行,且适用于提供的简单示例。
- 但实际应用程序中,编辑器很复杂(包括但不限于用于 Mayavi 场景的 SceneEditor),在处理时会销毁其所有内容。
- 想知道有没有一种更简单的方法可以在窗口处于活动状态时以动态方式更改特定 Item 或子面板的视图,无论通过简单的方法还是技巧。
2、解决方案
- 有一种方法可以以动态的方式更改激活窗口中 Trait 的视图,而无需销毁和重建视图对象。
- 这种方法涉及使用 ItemEditorFactory 类,该类允许动态创建和更新 Item 编辑器。
- 以下示例演示了如何使用 ItemEditorFactory 类来动态更改视图:
import traitsui.api
from traits.api import HasTraits, Instance, Enum, Range, Str, on_trait_change
class App(HasTraits):
info = Instance(traitsui.api.UIInfo)
view_type = Enum('slider_view', 'spinner_view')
number = Range(1, 10)
message = Str('sawmill')
def _create_editor_factory(self):
if self.view_type == 'slider_view':
return traitsui.api.RangeEditor(mode='slider', high=10, low=1)
elif self.view_type == 'spinner_view':
return traitsui.api.RangeEditor(mode='spinner', high=10, low=1)
editor_factory = Instance(traitsui.api.ItemEditorFactory)
def _get_editor_factory(self):
return self._create_editor_factory()
def _set_editor_factory(self, value):
self._editor_factory = value
self._update_editor()
@on_trait_change('view_type')
def _update_editor(self):
self.editor_factory = self._create_editor_factory()
view = View(Item('number',
editor=editor_factory,
label='Number'),
Item('message'),
Item('view_type'))
if __name__ == "__main__":
app = App()
app.configure_traits()
-
在此示例中,创建了一个
App类,它继承自HasTraits类。 -
App类具有三个属性:info、view_type和number。 -
info属性是traitsui.api.UIInfo类的实例,它存储有关 Traits UI 窗口的信息。 -
view_type属性是Enum类的实例,它可以是“slider_view”或“spinner_view”之一。 -
number属性是Range类的实例,它可以是 1 到 10 之间的任何整数。 -
还创建了一个
_create_editor_factory方法,它根据view_type属性的值返回一个ItemEditorFactory类的实例。 -
editor_factory属性是ItemEditorFactory类的实例,它用于创建和更新number属性的编辑器。 -
_get_editor_factory和_set_editor_factory方法是editor_factory属性的访问器和修改器。 -
_update_editor方法用于在更改view_type属性的值时更新number属性的编辑器。 -
最后,创建了一个
View对象,它定义了 Traits UI 窗口的布局。 -
在
if __name__ == "__main__":块中,创建了一个App类的实例并调用其configure_traits()方法来显示 Traits UI 窗口。 -
当用户更改
view_type属性的值时,_update_editor方法将被调用,该方法将创建一个新的ItemEditorFactory实例并将其分配给editor_factory属性。 -
这将导致
number属性的编辑器被更新,该编辑器将根据view_type属性的值而有所不同。