Search code examples
python-2.7enthoughttraitsui

How do I define the contents of a Traits/UI View programmatically?


I have a case in which I don't know the required contents (i.e. - set of Traits) of a HasTraits subclass, until program run time, because it depends upon the result of parsing a certain file with variable contents.

How can I customize the View for this HasTraits subclass programmatically, just before calling its configure_traits() method?

Here is a simple test case, which illustrates the problem:

#! /usr/bin/env python

'Test case, showing problem with dynamically constructed view.'

from traits.api   import HasTraits
from traitsui.api import View, Item

class DynamicViewTester(HasTraits):
    'Tries to dynamically construct its View, using default_traits_view().'

    def default_traits_view(self):
        view = View(
            Item(label='Hello, World!'),
            title='Dynamically Assembled View',
        )
        view.add_trait('msg', Item(label='Goodbye, World.'))
        return view

if(__name__ == '__main__'):
    DynamicViewTester().configure_traits()

When I run this code, I only see the "Hello, World!" message in the resultant GUI. I do NOT see the "Goodbye, World." message.


Solution

  • I found a solution:

    #! /usr/bin/env python
    
    'Test case, showing solution to dynamically constructed view problem.'
    
    from traits.api   import HasTraits, String
    from traitsui.api import View, Item
    
    class DynamicViewTester(HasTraits):
        'Dynamically construct its View, using default_traits_view().'
    
        def __init__(self, *args, **traits):
            super(DynamicViewTester, self).__init__(*args, **traits)
    
            # Here is where I'll parse the input file, constructing 'content' accordingly.
            content = []
            content.append(Item(label='Hello, World!'))
            content.append(Item(label='Goodbye, World.'))
    
            self._content = content
    
        def default_traits_view(self):
            view = View(
                title='Dynamically Assembled View',
                height=0.4,
                width=0.4,
            )
            view.set_content(self._content)
            return view
    
    if(__name__ == '__main__'):
        DynamicViewTester().configure_traits()