Search code examples
enthoughttraitsui

adding/changing 'text' to an item in a group


I'm designing a UI with Enthought's TraitsUI, and I can't figure out how to get done what I want...

Here's what I want: I have Items() in the view that I want to display as either English or SI units. I can change the value in the 'edit' box based on a SI/English button, but I can't figure out how to change the text of the label. For example, if I have an item 'Length, ft [ 3.28]' and convert it to SI, I'd like it to show 'Length, m [ 1.00]'. I can handle the 3.28->1.00 conversion, but can't figure out how to change the 'ft' to 'm'.

Any suggestions?

One thing I've tried is to define a string which holds the units name (like 'm' or 'ft')...then, in the item, I set the label like this:

label = 'Top, '+lengthUnits

This works fine when the view is first built, but it doesn't update the label when I change the units control. Is there some way to force the view to update with all the new values?

Here's a small py program that shows what I'm trying to do (feel free to critique my style :)). I'll also try and add in a couple of images that shows what happens:

# NOTE: This version of the code has been modified so that it works as I want it to :)

# Example trying to change text on a View...

from traits.api \
    import HasTraits, Enum, CFloat, String

from traitsui.api \
    import View, Group, HGroup, Item, spring

class TestDialog ( HasTraits ):
    length = CFloat(1.0)
    choose_units = Enum('English', 'SI')
    current_units = 'English'
    unit_name = String('ft')
    ft_to_m = CFloat(3.28)
    
    view = View(
        Group(
            HGroup(
                spring,
                Item(name = "length", label = 'Test length'),
                Item(name = 'unit_name', style = 'readonly', show_label = False),
                spring
            ),
            HGroup(
                spring,
                Item(name = "choose_units"),
                spring
            )
        ),
        title = 'Test Changing View Test'
    )

    def _choose_units_changed(self):
        if self.current_units != self.choose_units:
            if self.choose_units == 'SI':
                self.length /= self.ft_to_m
                self.unit_name = 'm'
            else:
                self.length *= self.ft_to_m
                self.unit_name = 'ft'
        self.current_units = self.choose_units
        
# Run the program (if invoked from the command line):
if __name__ == '__main__':
    # Create the dialog:
    TestIt = TestDialog()

    # put the actual dialog up...
    TestIt.configure_traits()

Screen Shot showing my issue


Solution

  • Use a notification as described here: http://code.enthought.com/projects/traits/docs/html/traits_user_manual/notification.html

    Update in response to updated question:

    Right, labels are not dynamically updated. Instead, make a text field that looks like a label, e.g. with:

    label_text = String('Test length, English:')
    

    Then display it in your View with something like:

    Item("label_text", style='readonly', show_label=False),
    

    You'll probably also want to use an HGroup nested inside your (V)Group, to position it to the left of your "length" display.

    Then modify label_text inside your listener.