0

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

Steve76063
  • 317
  • 2
  • 10

1 Answers1

1

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.

Jonathan March
  • 5,800
  • 2
  • 14
  • 16
  • Hmmm, not sure that will help...I'm using notifications now. I'm going to add to my post with a code snippet and some images to see if that helps explain what I'm trying to do... – Steve76063 Sep 18 '14 at 22:41
  • Updated the answer in response to snippet – Jonathan March Sep 19 '14 at 02:51
  • Perfect! That's _exactly_ what I was looking for :) PS, my 'real' program does use HGroups, I just didn't make this example too involved. – Steve76063 Sep 19 '14 at 14:03
  • 1
    Never mind...I just looked closely at your suggestion, and made the unit_name a String() trait...now it's working correctly :) Here's my original reply I was typing so it may help someone else who reads this (I've corrected the code snippet too): – Steve76063 Sep 19 '14 at 15:11
  • Glad it's working now. I appreciate that you updated the code snippet to help others, but to avoid confusion, I suggest that you put a clear note before the snippet to indicate that this is now the "after" code, not the "before". – Jonathan March Sep 19 '14 at 22:20