enabled_when listening outside model object

和自甴很熟 提交于 2019-12-08 05:24:49

问题


I found a workaround to my original problem but I am hoping someone else can explain what is going on. I originally noticed that enabled_when, and I'd imagine visible_when also, appears to take effect in response to trait events originating from the model object only. If the event originates from some other object, even if the editor refers to it, it doesn't seem to be propagated correctly.

class DirectObjectPronoun(HasTraits):
    text=Str
    typable=Bool(False)

    traits_view=View(
        Item(name='typable'),
        Item(name='text',enabled_when='typable'))

class IndirectObjectPronoun(HasTraits):
    referent=Instance(DirectObjectPronoun,())

    traits_view=View(
        Item(name='typable',object='object.referent'),
        Item(name='text',object='object.referent',
            enabled_when='object.referent.typable'))

IndirectObjectPronoun().configure_traits()

The desired behavior is that the text window is enabled when typable is True and disabled otherwise. The observed behavior is that the text window is always disabled (though if the default value of typable is set to True then it is always enabled, so the problem must be in the listener.)

If a DirectObjectPronoun is edited directly, the disabling works as intended.

I found a workaroud that that I don't understand.

class IndirectObjectPronoun(HasTraits):
    stupid_listener=Bool
    referent=Instance(DirectObjectPronoun,())

    traits_view=View(
        Item(name='typable',object='object.referent'),
        Item(name='text',object='object.referent',
            enabled_when='object.referent.typable'))

    @on_trait_change('referent.typable')
    def _stupid_listener_listens_stupidly(self):
        self.stupid_listener=self.referent.typable

The idea is pretty simple: make a stupid variable that does nothing but listen to the condition, and then set that local variable to be the condition.

However, when I was testing this I forgot to change enabled_when but it worked correctly anyway. In some way, adding this listener seems to have reminded the IndirectObjectPronoun that it's supposed to listen to this variable anyway. It also appears that the content of the _stupid_listener_listens_stupidly function matters -- if you change this to pass or print 56 or whatever, it no longer works.

Does anyone know what's going on here?


回答1:


Without studying the source, I don't know why it doesn't work; at very least, the inconsistency that you describe seems wrong.

A more intuitive workaround/solution is to use delegation:

class IndirectObjectPronoun(HasTraits):
    referent=Instance(DirectObjectPronoun,())
    typable = DelegatesTo('referent')

    traits_view=View(
        Item(name='typable',object='object.referent'),
        Item(name='text',object='object.referent',
             enabled_when='typable'))


来源:https://stackoverflow.com/questions/20409629/enabled-when-listening-outside-model-object

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