How do I make an edit_traits() GUI item responsive to changes in its dependencies?

醉酒当歌 提交于 2019-12-12 10:18:51

问题


I'm designing a HasTraits subclass with dependent properties:

#!/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()

When I run this code I see:

And if I change the value of Zap:

Note the following:

  1. After changing Zap, the address of Bar has changed.

    This means that changes to Bar are being dynamically updated in the GUI, while it's still opened; that's great! However...

  2. The way Bar is displayed in the GUI is not very useful.

    I'd love to have Bar displayed as Baz is displayed: selectable by the user.

What I'd like is to have the best of both worlds:

  • the dynamic GUI updating I see with Bar, and
  • the display format of Baz.

Does anyone know how I can get this?

I've tried several ways of updating a Baz-like item dynamically, to no avail. (See this previous SO question.)


回答1:


The following code gets me the behavior I want:

#!/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()

Immediately after program start-up:

And after changing to Zap to '1':




回答2:


I assume you wish both bar and baz to be dict type (in traits Dict). Actually, there are default display widgets for pre-defined trait types, which are more useful than showing address. I believe traitsui doesn't know how to properly display your custom Trait object unless you explicitly assign an editor for it. Note that for baz, although a dropdown menu is generated, it is only displaying the keys, which is not very useful either.

With that said, the following codes might meet your expectations.

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,
        )


来源:https://stackoverflow.com/questions/59010527/how-do-i-make-an-edit-traits-gui-item-responsive-to-changes-in-its-dependencie

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!