2

I am trying to figure out how Method traits work and if I can use one in a factory defined in a traits View object in order to have dynamic values passed to the factory.

Here is what I mean, a minimal test case which works except for the factory behavior (it runs, but using the factory will cause a crash):

from traits.api import HasTraits, Method, Str, List, Instance, method, Int, Any
from traitsui.api import View, Item, TableEditor, ObjectColumn, TextEditor

class Dog(HasTraits):
    name = Str('Fido')
    value = Int(5)

class DogTable(HasTraits):

    def factory(self):
        return Dog(value=self.current_user_value)    

    dog_factory = Method(factory)

    dogs = List(Instance(Dog))
    current_user_value = Int(3)

    def _dogs_default(self):
        return [
            Dog(name='Joe', value=6),
            Dog(name='Ted', value=2),
        ]

    traits_view = View(
        Item('dogs',
            editor=TableEditor( columns =
                [
                ObjectColumn(label='name', editor=TextEditor(), name='name'),
                ObjectColumn(label='value', editor=TextEditor(), name='value'),
                ],
               row_factory = dog_factory,
            )
        ),
        Item('current_user_value'),
        height=300, width=300,
    )

DogTable().configure_traits()

So what I am trying to do here is set up the factory so that the user can add new items to the table which contain as an initial value whatever value is currently specified by the user in the GUI.

Is there some way to do this? I thought that using a Method trait would resolve this problem by referring to the bound method and allow me to actually call the bound method in this instance, but it seems like Method's semantics are no different from Callable. And I can't figure out any way to supply arguments to the factory dynamically, other possibly than by hacky use of eval or global variables (factory_row_args rejects dynamic arguments).

aestrivex
  • 5,170
  • 2
  • 27
  • 44

1 Answers1

0

Yesterday I was very tired, today I thought of an obvious way to do it:

def dog_factory(self):
    return Dog(value=self.current_user_value)

def view_getter(self):
    return  View(
        Item('dogs',
            editor=TableEditor( columns =
                [
                ObjectColumn(label='name', editor=TextEditor(), name='name'),
                ObjectColumn(label='value', editor=TextEditor(), name='value'),
                ],  
               row_factory = self.dog_factory
            )
        ),
        Item('current_user_value'),
        height=300, width=300,
    )

def configure_traits(self):
    super(DogTable, self).configure_traits(view=self.view_getter())
aestrivex
  • 5,170
  • 2
  • 27
  • 44