首页 > 解决方案 > 如何使 edit_traits() GUI 项目响应其依赖项的变化?

问题描述

我正在设计一个HasTraits具有依赖属性的子类:

#!/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 后

请注意以下事项:

  1. 改了之后Zap,地址Bar就变了。

    这意味着更改Bar在 GUI 中动态更新,而它仍处于打开状态;那太棒了!然而...

  2. 在 GUI 中显示的方式Bar不是很有用。

    我很想Bar按原样Baz显示:用户可选择。

我想要的是两全其美:

有谁知道我怎么能得到这个?

我尝试了几种Baz动态更新类似项目的方法,但无济于事。(请参阅this previous SO question。)

标签: propertiesenthoughttraitsui

解决方案


我假设您希望两者都bar成为baz类型dict(在 traits 中Dict)。实际上,预定义的 trait 类型有默认的显示小部件,这比显示地址更有用。我相信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,
        )

推荐阅读