Search code examples
pythontraitsenthoughttraitsui

TraitsUI TextEditor enter_set causes input to be rejected


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()

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.