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?
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: