Flow Area Example
An example of the FlowArea
widget.
A FlowArea
is a very powerful tool for creating a flowing layout of
widgets. A FlowArea
accepts an arbitrary number of FlowItem
children,
each of which holds a Container
as its content. The layout of these
FlowItem
children is controlled by the FlowArea
attributes:
direction
This is an enum controlling how the items are arranged in the area. Allowable values are ‘left_to_right’, ‘right_to_left’, ‘top_to_bottom’, and ‘bottom_to_top’; and indicate the direction in which items will be added to the area. When the layout space in a given direction is exhausted, the layout will wrap around to the next line. With horizontal directions, lines are stacked top to bottom. With vertical directions, lines are stacked left to right.
align
This is an enum controlling how a layout line is aligned within the layout space. If there is any space leftover after laying out a given line of widgets, that space is distributed according to the value of this enum. Allowable values are ‘leading’, ‘trailing’, ‘center’, and ‘justify’.
horizontal_spacing
This is an int specifying how much horizontal space to place between items or lines in the layout.
vertical_spacing
This is an int specifying how much vertical space to place between items or lines in the layout.
margins
This is a Box of ints specifying how much margin to place on the outside of the layout.
Each FlowItem
used in the layout can further customize the behavior:
preferred_size
This is a Size specifying the desired layout size for the item. This size will be used whenever possible, but will not override the minimum or maximum size of the item. If set to (-1, -1) (the default), then the size hint for the item will be used.
align
This is an enum which controls the orthogonal alignment of the item. When an item has neighbors which are larger than itself in the orhthongonal direction, this value controls how the item aligns within that additional space. The valid values area ‘leading’, ‘trailing’, and ‘center’.
stretch
This is an int which controls the amount that the widget should expand to take up additional space in the layout direction. The default is 0 and means that the widget will not expand. When the value is greater than zero, the value is weighted against the stretch factors of the other items in the same line to determine the amount of space given to the item.
ortho_stretch
This is an int which controls the amount that the widget should expand to take up additional space orthogonal to the layout direction. The default is 0 and means that the widget will not expand. If no item in a given line can expand in the ortho direction, then the line will not expand. Otherwise, the stretch factor for a line is equivalent to the maximum of the ortho stretch factors for all items in the line. The extra orthogonal space is then proportioned to the lines weighted on this stretch factor.
The code below creates a flow area populated with several initial flow items. Items can be added and removed, and each individual item is configurable. There is a single item which cannot be removed, and which controls the parameters for the entire area.
Screenshot

Example Enaml Code
#------------------------------------------------------------------------------
# Copyright (c) 2013-2024, Nucleic Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
#------------------------------------------------------------------------------
""" An example of the `FlowArea` widget.
A `FlowArea` is a very powerful tool for creating a flowing layout of
widgets. A `FlowArea` accepts an arbitrary number of `FlowItem` children,
each of which holds a `Container` as its content. The layout of these
`FlowItem` children is controlled by the `FlowArea` attributes:
`direction`
This is an enum controlling how the items are arranged in the
area. Allowable values are 'left_to_right', 'right_to_left',
'top_to_bottom', and 'bottom_to_top'; and indicate the direction
in which items will be added to the area. When the layout space
in a given direction is exhausted, the layout will wrap around
to the next line. With horizontal directions, lines are stacked
top to bottom. With vertical directions, lines are stacked
left to right.
`align`
This is an enum controlling how a layout line is aligned within
the layout space. If there is any space leftover after laying
out a given line of widgets, that space is distributed according
to the value of this enum. Allowable values are 'leading',
'trailing', 'center', and 'justify'.
`horizontal_spacing`
This is an int specifying how much horizontal space to place
between items or lines in the layout.
`vertical_spacing`
This is an int specifying how much vertical space to place
between items or lines in the layout.
`margins`
This is a Box of ints specifying how much margin to place
on the outside of the layout.
Each `FlowItem` used in the layout can further customize the behavior:
`preferred_size`
This is a Size specifying the desired layout size for the item.
This size will be used whenever possible, but will not override
the minimum or maximum size of the item. If set to (-1, -1)
(the default), then the size hint for the item will be used.
`align`
This is an enum which controls the orthogonal alignment of the
item. When an item has neighbors which are larger than itself
in the orhthongonal direction, this value controls how the item
aligns within that additional space. The valid values area
'leading', 'trailing', and 'center'.
`stretch`
This is an int which controls the amount that the widget should
expand to take up additional space in the layout direction. The
default is 0 and means that the widget will not expand. When the
value is greater than zero, the value is weighted against the
stretch factors of the other items in the same line to determine
the amount of space given to the item.
`ortho_stretch`
This is an int which controls the amount that the widget should
expand to take up additional space orthogonal to the layout
direction. The default is 0 and means that the widget will not
expand. If no item in a given line can expand in the ortho
direction, then the line will not expand. Otherwise, the stretch
factor for a line is equivalent to the maximum of the ortho
stretch factors for all items in the line. The extra orthogonal
space is then proportioned to the lines weighted on this stretch
factor.
The code below creates a flow area populated with several initial flow
items. Items can be added and removed, and each individual item is
configurable. There is a single item which cannot be removed, and which
controls the parameters for the entire area.
<< autodoc-me >>
"""
from enaml.core.api import Include
from enaml.widgets.api import (
FlowArea, FlowItem, Window, Form, Label, Field, SpinBox, ComboBox,
Container, Html, GroupBox, Slider, PushButton,
)
enamldef Item(FlowItem):
align << align_box.selected_item
stretch << flow_spin.value
ortho_stretch << ortho_spin.value
preferred_size << (pref_width.value, pref_height.value)
GroupBox:
Form:
padding = 0
Label:
text = 'Preferred Width'
SpinBox: pref_width:
minimum = -1
maximum = 800
value = -1
Label:
text = 'Preferred Height'
SpinBox: pref_height:
minimum = -1
maximum = 800
value = -1
Label:
text = 'Flow Stretch'
SpinBox: flow_spin:
minimum = 0
maximum = 100
value = 0
Label:
text = 'Ortho Stretch'
SpinBox: ortho_spin:
minimum = 0
maximum = 100
value = 0
Label:
text = 'Ortho Align'
ComboBox: align_box:
items = ['leading', 'center', 'trailing']
index = 0
Html:
source = '<center>Hello World</center>'
enamldef AreaControls(GroupBox):
attr area: FlowArea
event add_item
event remove_item
title = 'Area Controls'
Label:
text =('Add new items to see how the flow area works.\n'
'You can also tweak the flow parameters')
PushButton:
text = 'Add Item'
clicked :: add_item()
PushButton:
text = 'Remove Item'
clicked :: remove_item()
Form:
padding = 0
Label:
text = 'Horizontal Spacing'
Slider:
minimum = 0
maximum = 150
value := area.horizontal_spacing
Label:
text = 'Vertical Spacing'
Slider:
minimum = 0
maximum = 150
value := area.vertical_spacing
Label:
text = 'Direction'
ComboBox:
items = [
'left_to_right', 'right_to_left',
'top_to_bottom', 'bottom_to_top',
]
index = items.index(area.direction)
selected_item >> area.direction
Label:
text = 'Align'
ComboBox:
items = ['leading', 'center', 'justify', 'trailing']
index = items.index(area.align)
selected_item >> area.align
enamldef Main(Window):
initial_size = (800,800)
Container:
FlowArea: flow_area:
FlowItem:
AreaControls:
area = flow_area
add_item ::
inc.objects.append(Item())
remove_item ::
if inc.objects:
inc.objects.pop()
Include: inc:
pass