1

I want to make reusable Container with a title in the like in the banner example. (So it is like a custom GroupBox). So every element i add to the class should be added to the classes subcontainer, not to itself. See the code below, i marked the position where i just want to write the subelements.

from enaml.widgets.api import *
from enaml.layout.api import *
from enaml.styling import *

enamldef BannerSheet(StyleSheet):
    Style:
        element = 'Label'
        style_class = 'banner'
        Setter:
            field = 'background'
            value = ('lineargradient(x1: 0, y1:0, x2:0, y2:1, '
                        'stop: 0 #222222, stop: 0.5 #1A1A1A, stop: 1 #111111)')
        Setter:
            field = 'color'
            value = '#FFFFEF'
        Setter:
            field = 'padding'
            value = '5px'
        Setter:
            field = 'font'
            value = '18pt Verdana'

enamldef Banner(Container):
    BannerSheet:
        pass
    padding = 0
    alias title : lbl.text
    constraints = [lbl.left == left, 
                   lbl.right == right, 
                   con.top == lbl.bottom,
                   con.bottom<=bottom]
    Label: lbl:
        name = 'abd'   
        style_class = 'banner'

    Container: con:
        pass


enamldef DemoContainer(Container):
    padding = 0
    Banner: b:
        title = 'Bar'
        #i want children here to be put into the banner.con container.
        #so e.g.
        Label:
             text = 'This should be below the title label"
tillsten
  • 14,491
  • 5
  • 32
  • 41
  • Could you expand on "this isn't working" and explain what you would expect when it is working? Also, you said you want to override `add_child` but in the code only `child_added` is overridden. Is that an error? – KobeJohn Mar 02 '14 at 13:11
  • You are right, child_add is the wrong method. BUt as far as i can tell there is no add_child. There is a insert_children method, but calling it crashs the interpreter. – tillsten Mar 02 '14 at 15:09
  • I'm more confused now. Please explain more about what you expect to happen and what is actually happening when you use the code you pasted. – KobeJohn Mar 02 '14 at 15:15
  • As i wrote, my code is probly wrong. So i'll try to explain more clearly what i want. There is the nice banner example in the styling examples of enamal. I would like do a reusable class/enamldef, which has a title attribute and accepts childs like a simple container. – tillsten Mar 02 '14 at 15:25
  • Could you add that to the original question, add an example of how you would like to call/use your class, and also add a link to the example you mentioned? – KobeJohn Mar 02 '14 at 15:34

1 Answers1

2

Enaml doesn't allow you to delegate the position of a widget in the hierarchy using the declarative syntax (you can do it with Include and procedural code). Your simplest option is to use a child Container on the banner, which holds the widgets. Something like the following:

from enaml.widgets.api import *


enamldef BannerContainer(Container):
    alias text: label.text
    Label: label:
        pass


enamldef Main(Window):
    Container:
        BannerContainer:
            text = 'First Banner'
            Container:
                padding = 0
                Field: pass
                Field: pass
                Field: pass
        BannerContainer:
            text = 'Second Banner'
            Container:
                padding = 0
                PushButton: pass
                PushButton: pass
                PushButton: pass

enter image description here

Alternatively, you can subclass container and reimplement the layout_constraints method to do whatever you want for layout purposes (see the TaskDialog implementation for an example of this), or use templates and a compile-time for-each loop to expand the child widgets (see the advanced template example).

Chris Colbert
  • 868
  • 7
  • 12