Dynamically creating Views

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Dynamically creating Views

CBeres

I have a situation where I want to create dialog with some options, but I don't know exactly what options or how many options will be available when I run the program.  I tried a few things so far including set_content(), Include, and giving the configure_traits() function a View, but nothing seems to work.  I see there's also a replace_include() function, but I can't figure out how to use it.  Below is my attempt at getting this working.

I think I can use the get() function to get the traits' values, but how can I dynamically create a View?

from enthought.traits.api import *
from enthought.traits.ui.api import View, Item, Group, HGroup, VGroup, Include
from enthought.traits.ui.menu import *

class UiTest(HasTraits):
    "Tries to create a View dynamically."

    # UI Items
    uiItems = []

    my_ui = View(
                 #Include('my_group'),
                 title   = 'Metrics',
                 buttons = ['OK', 'Cancel']
    )

    def __init__(self):
        traits = ['bool1', 'bool2', 'bool4', 'bool7', 'bool9']
        self.traits = traits

        # Define some traits
        for trait in traits:
            self.add_trait(trait, Bool)
            self.uiItems.append(Item(name = trait))

        # UI for choosing capabilities
        print self.uiItems
        self.my_ui.set_content(*self.uiItems)

        # Also tried Include
        #self.my_group = Group(*self.uiItems)

        # Also tried defining UI down here
        #self.my_ui = View(
        #                    *self.uiItems,
        #                    title   = 'Choose the metrics',
        #                    buttons = ['OK', 'Cancel']
        #)

    def GetItems(self):
        return self.uiItems

# main section
test = UiTest()

# ask user to select device
test.configure_traits()
# Tried this, too
#items = test.GetItems()
#test.configure_traits(view=View(*items,title='Metrics',buttons=['OK', 'Cancel']))


Here's the output:

[Item( 'bool1' ), Item( 'bool2' ), Item( 'bool4' ), Item( 'bool7' ), Item( 'bool
9' )]
Traceback (most recent call last):
  File "UiTest.py", line 45, in <module>
    test = UiTest()
  File "UiTest.py", line 29, in __init__
    self.my_ui.set_content(*self.uiItems)
AttributeError: 'UiTest' object has no attribute 'my_ui'
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Dynamically creating Views

bryce hendrix-2
On 07/02/2010 08:19 AM, [hidden email] wrote:

I have a situation where I want to create dialog with some options, but I don't know exactly what options or how many options will be available when I run the program.  I tried a few things so far including set_content(), Include, and giving the configure_traits() function a View, but nothing seems to work.  I see there's also a replace_include() function, but I can't figure out how to use it.  Below is my attempt at getting this working.

Try declaring your view in a method, such as trait_view:

def trait_view(self, parent=None):
    return View(...)

Bryce


I think I can use the get() function to get the traits' values, but how can I dynamically create a View?

from enthought.traits.api import *
from enthought.traits.ui.api import View, Item, Group, HGroup, VGroup, Include
from enthought.traits.ui.menu import *

class UiTest(HasTraits):
    "Tries to create a View dynamically."

    # UI Items
    uiItems = []

    my_ui = View(
                 #Include('my_group'),
                 title   = 'Metrics',
                 buttons = ['OK', 'Cancel']
    )

    def __init__(self):
        traits = ['bool1', 'bool2', 'bool4', 'bool7', 'bool9']
        self.traits = traits

        # Define some traits
        for trait in traits:
            self.add_trait(trait, Bool)
            self.uiItems.append(Item(name = trait))

        # UI for choosing capabilities
        print self.uiItems
        self.my_ui.set_content(*self.uiItems)

        # Also tried Include
        #self.my_group = Group(*self.uiItems)

        # Also tried defining UI down here
        #self.my_ui = View(
        #                    *self.uiItems,
        #                    title   = 'Choose the metrics',
        #                    buttons = ['OK', 'Cancel']
        #)

    def GetItems(self):
        return self.uiItems

# main section
test = UiTest()

# ask user to select device
test.configure_traits()
# Tried this, too
#items = test.GetItems()
#test.configure_traits(view=View(*items,title='Metrics',buttons=['OK', 'Cancel']))


Here's the output:

[Item( 'bool1' ), Item( 'bool2' ), Item( 'bool4' ), Item( 'bool7' ), Item( 'bool
9' )]
Traceback (most recent call last):
  File "UiTest.py", line 45, in <module>
    test = UiTest()
  File "UiTest.py", line 29, in __init__
    self.my_ui.set_content(*self.uiItems)
AttributeError: 'UiTest' object has no attribute 'my_ui'
_______________________________________________ Enthought-Dev mailing list [hidden email] https://mail.enthought.com/mailman/listinfo/enthought-dev


_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Dynamically creating Views

Robert Kern
On Tue, Jul 6, 2010 at 7:54 PM, bryce hendrix <[hidden email]> wrote:

> On 07/02/2010 08:19 AM, [hidden email] wrote:
>
> I have a situation where I want to create dialog with some options, but I
> don't know exactly what options or how many options will be available when I
> run the program.  I tried a few things so far including set_content(),
> Include, and giving the configure_traits() function a View, but nothing
> seems to work.  I see there's also a replace_include() function, but I can't
> figure out how to use it.  Below is my attempt at getting this working.
>
> Try declaring your view in a method, such as trait_view:
>
> def trait_view(self, parent=None):
>     return View(...)

No, that's wrong. Use "def default_traits_view(self):". A
properly-written trait_view() implementation is more complicated.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless
enigma that is made terrible by our own mad attempt to interpret it as
though it had an underlying truth."
  -- Umberto Eco
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Dynamically creating Views

bryce hendrix-2
On 07/06/2010 02:59 PM, Robert Kern wrote:

> On Tue, Jul 6, 2010 at 7:54 PM, bryce hendrix<[hidden email]>  wrote:
>    
>> On 07/02/2010 08:19 AM, [hidden email] wrote:
>>
>> I have a situation where I want to create dialog with some options, but I
>> don't know exactly what options or how many options will be available when I
>> run the program.  I tried a few things so far including set_content(),
>> Include, and giving the configure_traits() function a View, but nothing
>> seems to work.  I see there's also a replace_include() function, but I can't
>> figure out how to use it.  Below is my attempt at getting this working.
>>
>> Try declaring your view in a method, such as trait_view:
>>
>> def trait_view(self, parent=None):
>>      return View(...)
>>      
> No, that's wrong. Use "def default_traits_view(self):". A
> properly-written trait_view() implementation is more complicated.
>    

Yes, Robert is correct. I've been away from Traits for a few weeks...

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Dynamically creating Views

CBeres

[hidden email] wrote on 07/06/2010 04:03:05 PM:

> On 07/06/2010 02:59 PM, Robert Kern wrote:
> > On Tue, Jul 6, 2010 at 7:54 PM, bryce hendrix<bhendrix@enthought.
> com>  wrote:
> >    
> >> On 07/02/2010 08:19 AM, [hidden email] wrote:
> >>
> >> I have a situation where I want to create dialog with some options, but I
> >> don't know exactly what options or how many options will be
> available when I
> >> run the program.  I tried a few things so far including set_content(),
> >> Include, and giving the configure_traits() function a View, but nothing
> >> seems to work.  I see there's also a replace_include() function,
> but I can't
> >> figure out how to use it.  Below is my attempt at getting this working.
> >>
> >> Try declaring your view in a method, such as trait_view:
> >>
> >> def trait_view(self, parent=None):
> >>      return View(...)
> >>      
> > No, that's wrong. Use "def default_traits_view(self):". A
> > properly-written trait_view() implementation is more complicated.
> >    
>
> Yes, Robert is correct. I've been away from Traits for a few weeks...
>

Awesome! Thank you very much. I'm glad the solution was so simple:

from enthought.traits.api import *
from enthought.traits.ui.api import View, Item, Group, HGroup, VGroup
from enthought.traits.ui.menu import *

class UiTest(HasTraits):
    "Tries to create a View dynamically."

    def __init__(self):
        self.mytraits = ['bool_1', 'bool2', 'bool4', 'bool7', 'bool9']

        # Define some traits
        for t in self.mytraits:
            self.add_trait(t, Bool)

    def default_traits_view(self):
        return View(*self.mytraits, title = 'Bools', buttons = ['OK', 'Cancel'])

# main section
test = UiTest()

# ask user to select options
test.configure_traits()

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Dynamically creating Views

ericjmcd
This post was updated on .
Sorry to bump this old thread but the above solution didn't work for my case.  I need to have the view dynamic at runtime so with the help of the above solution and another I found elsewhere I came up with the following.  I wanted to post it in the chance that someone else needs this kind of functionality.
(Note that what I want to do could be done with a Table/Tabular-Editor but I didn't want to use that editor and this solution is useful beyond my simple case.)

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

class DynamicObject(HasTraits):
    config_list = List
    options_list = List
   
    def __init__(self, **kws):
        super(DynamicObject, self).__init__(**kws)
        self.items = [] # will contain trait names
        for i in self.config_list:
            self.add_trait(i, Enum(self.options_list))
            self.items.append(i) # simple string addition (default Item)
            self.items.append(Item(i, style='readonly')) # complex Item
       
    def default_traits_view(self):
        return View(*self.items,
                         resizable=True)
       

class demo(HasTraits):
    trigger = Button("Change !")
    obj = Instance(DynamicObject)
    def _obj_default(self):
        return DynamicObject(config_list=self.config_list,
                      options_list=self.options_list)
    options_list = List
    config_list = List

    view = View ( UCustom('obj'),
                  Item('trigger'),
                  resizable=True)
 
    def _trigger_fired(self):
        if len(self.options_list) != 2:
            self.options_list = ['4','5']
            self.config_list = ['d','e','f','g']
        else:
            self.options_list = ['1','2','3']
            self.config_list = ['a','b','c']
           
        self.obj = DynamicObject(config_list=self.config_list,
                                 options_list=self.options_list)
       
demo().configure_traits()