Label {visible/enabled}_when#1544
Conversation
|
orthogonal to this change, i'm really interested in refactoring the this might make for an interesting pair programming session. |
|
The layout generation code is a continuing source of problems - it is opaque, custom for each backend, and not dynamic. The right way to fix this is to add a cross-toolkit abstraction of layout, tabs, splitters, etc. and have them controlling the layout dynamically and accessible from the main UI object. In the meantime, do the best you can with what we have :/ |
|
I am finding it quite difficult to write a regression test for this... I am unable to even get my hands on the correct I am hopeful I'm missing something trivial and this can be done in a much simpler way. For right now I think I am going to stop looking into this as I feel like I am making no progress on something which feels like it should be so simple. |
|
|
||
| if (len(self._label_enabled_whens) + len(self._label_visible_whens)) > 0: | ||
| for object in self.ui.context.values(): | ||
| object.on_trait_change(lambda: self._label_when(), dispatch="ui") |
There was a problem hiding this comment.
ideally we would call self._label_when() after this for loop, just like we do in the qt version. The problem is, if we do this, if you run the following example:
from traits.api import HasTraits, Int, Str
from traitsui.api import View, Item, Label, HGroup
class A(HasTraits):
x = Int(1)
view = View(
Label("Visible", visible_when="x != 0"),
Label("Enabled", enabled_when="x != 0"),
Item('x'),
resizable=True
)
if __name__ == '__main__':
A().configure_traits()
you will never be able to see a "Visible" label, even if you change x to not be 0. (enabled works perfectly fine). I think the reason is that, if we set the label to invisible right off the bat, it doesn't get included in the layout or something like this. Then everytime in the future, showing/hiding it does nothing.
If we don't have self._label_when() (as is currently the case), then by default both the "Visible" and "Enabled" labels are shown at the start, (even though we shouldn't see "Visible" and "Enabled" should be greyed out). From then on whenever anything is changed on the UI they will get synced up with their enabled_when/visible_when expressions and work as desired.
This is not ideal, but better than just not working at all. I could not find a way to have the visible label be invisible to start, but then show up later if the visible_when condition ever got switched to True.
There was a problem hiding this comment.
let's convert this into an issue
rahulporuri
left a comment
There was a problem hiding this comment.
LGTM. I tested this on qt with the MRE in the issue and this solution works as expected.
Tangentially, it looks like we can continue refactoring the toolkit-specific ui_panel classes.
closes #298
This PR is miles away from being ready for a review. At this point it is basically chicken scratch to try and get something to work. I would like to have a discussion about possible approaches for how to best solve the issue. The current start of an implementation here I don't image will be how we wish to proceed long term.Nonetheless, the solution here for qt only seems to work as expected, at least for the simple examples I have tried, eg. the ones described on the issue. I effectively tried to recreate the approach used to handle {visible/enabled}_when intraitsui.ui.pyonly to match the slightly different scenario.This PR provides a solution for having
Labels respect theirenabled_whenandvisible_whentraits. The solution on qt works exactly as expected.I had a hiccup with wx:
basically with wx if you try to do the
self._label_when()call immediately, if one of the labels has a visible_when expression evaluating toFalseinitially, it will never be able to toggle back on. see comments on the code changes for more details. Thus, currently the enabled_when/visible_when could start incorrect but as soon as any trait in the uis context changes they are then correct/will remain in sync.There is no unittest here (I really struggled trying to write one for this code). I can open an issue to add one