如何使 edit_traits() GUI 项响应其依赖项的变化?
How do I make an edit_traits() GUI item responsive to changes in its dependencies?
我正在设计一个 HasTraits
具有 dependent 属性的子类:
#!/usr/bin/env python
# Example for SO question on dynamically changing Dict contents.
from traits.api import HasTraits, Dict, Property, Trait, Int, cached_property
from traitsui.api import View, Item
class Foo(HasTraits):
"Has dependent properties, which I'd like to remain up-to-date in the GUI."
_dicts = [
{"zero": 0, "one": 1},
{"zero": 1, "one": 2},
{"zero": 2, "one": 3},
]
zap = Int(0)
bar = Property(Trait, depends_on=["zap"])
baz = Trait(list(_dicts[0])[0], _dicts[0])
@cached_property
def _get_bar(self):
return Trait(list(self._dicts)[self.zap], self._dicts)
traits_view = View(
Item("zap"),
Item("bar"),
Item("baz"),
width=500,
)
if __name__ == '__main__':
Foo().configure_traits()
当我 运行 我看到这段代码时:
如果我更改 Zap
的值:
注意以下几点:
改Zap
后,Bar
的地址变了
这意味着对 Bar
的更改正在 GUI 中动态更新,同时它仍处于打开状态;那太棒了!然而...
在 GUI 中显示 Bar
的方式不是很有用。
我希望 Bar
显示为 Baz
:可由用户选择。
我想要的是两全其美:
- 我看到
Bar
和 的动态 GUI 更新
Baz
. 的显示格式
有谁知道我怎样才能得到这个?
我尝试了几种动态更新类似 Baz
的项目的方法,但都无济于事。
(参见 。)
我假设您希望 bar
和 baz
都是 dict
类型(在特征 Dict
中)。实际上,预定义特征类型有默认的显示小部件,这比显示地址更有用。我相信 traitsui
不知道如何正确显示您的自定义 Trait 对象,除非您明确为其指定一个编辑器。注意,对于baz,虽然生成了下拉菜单,但它只是显示按键,这也不是很有用。
话虽如此,以下代码可能符合您的预期。
class Foo(HasTraits):
"Has dependent properties, which I'd like to remain up-to-date in the GUI."
_dicts = [
{"zero": 0, "one": 1},
{"zero": 1, "one": 2},
{"zero": 2, "one": 3},
]
zap = Int(0)
bar = Property(Dict, depends_on=["zap"])
baz = Trait(list(_dicts[0])[0], _dicts[0])
@cached_property
def _get_bar(self):
return self._dicts[self.zap]
traits_view = View(
Item("zap"),
Item("bar", style="custom"),
Item("baz"),
width=500,
)
下面的代码让我得到我想要的行为:
#!/usr/bin/env python
# Example for SO question on dynamically changing Dict contents.
from traits.api import HasTraits, Dict, Property, Trait, Int, cached_property, Enum, List
from traitsui.api import View, Item
class Foo(HasTraits):
"Has dependent properties, which I'd like to remain up-to-date in the GUI."
_dict = {
"zero": 0,
"one": 1,
"two": 2,
}
_zaps = [
["zero", "one"],
["one", "two"],
["zero", "two"],
]
zaps = List(_zaps[0])
zap = Enum([0,1,2]) # Selection of `zap` should limit the items of `_dict` available for selection.
bar = Enum(_zaps[0][0], values="zaps")
bar_ = Int(_dict[_zaps[0][0]])
def _zap_changed(self, new_value):
self.zaps = self._zaps[new_value]
self.bar_ = self._dict[self.bar]
def _bar_changed(self, new_value):
self.bar_ = self._dict[self.bar]
traits_view = View(
Item("zap"),
Item("bar"),
Item("bar_", style="readonly"),
width=500,
)
if __name__ == '__main__':
Foo().configure_traits()
程序启动后立即:
并且在将 Zap
更改为 '1' 之后:
我正在设计一个 HasTraits
具有 dependent 属性的子类:
#!/usr/bin/env python
# Example for SO question on dynamically changing Dict contents.
from traits.api import HasTraits, Dict, Property, Trait, Int, cached_property
from traitsui.api import View, Item
class Foo(HasTraits):
"Has dependent properties, which I'd like to remain up-to-date in the GUI."
_dicts = [
{"zero": 0, "one": 1},
{"zero": 1, "one": 2},
{"zero": 2, "one": 3},
]
zap = Int(0)
bar = Property(Trait, depends_on=["zap"])
baz = Trait(list(_dicts[0])[0], _dicts[0])
@cached_property
def _get_bar(self):
return Trait(list(self._dicts)[self.zap], self._dicts)
traits_view = View(
Item("zap"),
Item("bar"),
Item("baz"),
width=500,
)
if __name__ == '__main__':
Foo().configure_traits()
当我 运行 我看到这段代码时:
如果我更改 Zap
的值:
注意以下几点:
改
Zap
后,Bar
的地址变了这意味着对
Bar
的更改正在 GUI 中动态更新,同时它仍处于打开状态;那太棒了!然而...在 GUI 中显示
Bar
的方式不是很有用。我希望
Bar
显示为Baz
:可由用户选择。
我想要的是两全其美:
- 我看到
Bar
和 的动态 GUI 更新
Baz
. 的显示格式
有谁知道我怎样才能得到这个?
我尝试了几种动态更新类似 Baz
的项目的方法,但都无济于事。
(参见
我假设您希望 bar
和 baz
都是 dict
类型(在特征 Dict
中)。实际上,预定义特征类型有默认的显示小部件,这比显示地址更有用。我相信 traitsui
不知道如何正确显示您的自定义 Trait 对象,除非您明确为其指定一个编辑器。注意,对于baz,虽然生成了下拉菜单,但它只是显示按键,这也不是很有用。
话虽如此,以下代码可能符合您的预期。
class Foo(HasTraits):
"Has dependent properties, which I'd like to remain up-to-date in the GUI."
_dicts = [
{"zero": 0, "one": 1},
{"zero": 1, "one": 2},
{"zero": 2, "one": 3},
]
zap = Int(0)
bar = Property(Dict, depends_on=["zap"])
baz = Trait(list(_dicts[0])[0], _dicts[0])
@cached_property
def _get_bar(self):
return self._dicts[self.zap]
traits_view = View(
Item("zap"),
Item("bar", style="custom"),
Item("baz"),
width=500,
)
下面的代码让我得到我想要的行为:
#!/usr/bin/env python
# Example for SO question on dynamically changing Dict contents.
from traits.api import HasTraits, Dict, Property, Trait, Int, cached_property, Enum, List
from traitsui.api import View, Item
class Foo(HasTraits):
"Has dependent properties, which I'd like to remain up-to-date in the GUI."
_dict = {
"zero": 0,
"one": 1,
"two": 2,
}
_zaps = [
["zero", "one"],
["one", "two"],
["zero", "two"],
]
zaps = List(_zaps[0])
zap = Enum([0,1,2]) # Selection of `zap` should limit the items of `_dict` available for selection.
bar = Enum(_zaps[0][0], values="zaps")
bar_ = Int(_dict[_zaps[0][0]])
def _zap_changed(self, new_value):
self.zaps = self._zaps[new_value]
self.bar_ = self._dict[self.bar]
def _bar_changed(self, new_value):
self.bar_ = self._dict[self.bar]
traits_view = View(
Item("zap"),
Item("bar"),
Item("bar_", style="readonly"),
width=500,
)
if __name__ == '__main__':
Foo().configure_traits()
程序启动后立即:
并且在将 Zap
更改为 '1' 之后: