Question

I am trying to build a traitsui application. As part of this application, I listen to a float that the user inputs. The editor for this float by default is a TextEditor with auto_set on. However, when the user finishes inputting this number the program does a long computation, so it is really annoying when the program listens to the new trait 1 when the user really wanted to enter 1.7.

I tried to solve this problem with the enter_set attribute of the TextEditor factory. But, when I do this, it doesn't allow the trait to be updated at all and the box appears in red no matter what value is entered. This is clearly not how enter_set and auto_set are supposed to work. What am I doing wrong?

Here's my test code:

from traits.api import *
from traitsui.api import *

class FloatEditorClass(HasTraits):
  f=Float
  click=Button('clickme')

  view=View(Item('f',editor=TextEditor(auto_set=False,enter_set=True)),
    # removing one or the other of these settings doesn't change anything
    Item(name='click'))

  def _click_fired(self):
    print self.f

fec=FloatEditorClass()
fec.configure_traits()
Was it helpful?

Solution

You can use CFloat instead of Float, which tries to transform the value you assign to the trait to float. If you try to assign a string to Float, it detects that the type is wrong.

For example:

class CFloatDemo(HasTraits):
    f = Float
    cf = CFloat

demo = CFloatDemo()

demo.f = '3.0'  # This raises a TraitError
demo.cf = '3.0' # This assigns 3.0 to 'cf'

Update:

The other option is to tell the TextEditor how to map the string to the traits value:

traits_view=View(
   Item('f', editor=TextEditor(auto_set=False,enter_set=True, evaluate=float)),
   Item(name='click')
)

This is how the default editor for Float is set up by Traits UI.

OTHER TIPS

Actually, I figured out what my own problem was, and while I would argue this is unavoidably a bug in the editor factory, I do have a fix.

The problem is that when you enter into a text editor, say the string '4', the editor interprets your string as precisely this, the string '4' and not the number. If you specify an Int trait and let it use its default editor, it must do something unseen to convert this string to an int (probably, it just specifies the function int() as the 'evaluate' attribute of the editor).

Instead, if you specify the editor yourself with the parameter fixes you are interested in, this fix is bypassed (which is a bug in TextEditor, or perhaps a bug of python itself if you argue that duck typing is inherently an error), so you have to supply the fix (e.g. the evaluate parameter) yourself. As an equivalent solution that is slightly easier in the general case, use the DefaultOverride factory instead which was created for this purpose.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top