Box¶
The box layout classes provide a simple mechanism to horizontally
or vertically stack child widgets. The BoxLayout
(and HBox
and
VBox
) are intended for laying out leaf content taking into account the
natural size of the child widgets. The BoxPanel
(and HBoxPanel
and
VBoxPanel
) are intended for higher-level layout. Instead of the “natural”
size of a widget, the widgets base_size
property is used as the
“reference” size.
In chosing between these two kinds of layouts, one could ask oneself whether
the layout can be replaced by a SplitPanel
. If it can, use a BoxPanel
.
Example for BoxLayout:
from flexx import ui
class Example(ui.Widget):
def init(self):
with ui.BoxLayout(orientation='v'):
ui.Label(text='Flex 0 0 0')
with ui.HBox(flex=0):
self.b1 = ui.Button(text='Hola', flex=0)
self.b2 = ui.Button(text='Hello world', flex=0)
self.b3 = ui.Button(text='Foo bar', flex=0)
ui.Label(text='Flex 1 0 3')
with ui.HBox(flex=0):
self.b1 = ui.Button(text='Hola', flex=1)
self.b2 = ui.Button(text='Hello world', flex=0)
self.b3 = ui.Button(text='Foo bar', flex=3)
ui.Label(text='padding 10 (around layout)')
with ui.HBox(flex=0, padding=10):
self.b1 = ui.Button(text='Hola', flex=1)
self.b2 = ui.Button(text='Hello world', flex=1)
self.b3 = ui.Button(text='Foo bar', flex=1)
ui.Label(text='spacing 10 (inter-widget)')
with ui.HBox(flex=0, spacing=10):
self.b1 = ui.Button(text='Hola', flex=1)
self.b2 = ui.Button(text='Hello world', flex=1)
self.b3 = ui.Button(text='Foo bar', flex=1)
ui.Widget(flex=1)
ui.Label(text='Note the spacer Widget above')
A similar example using a BoxPanel:
from flexx import ui
class Example(ui.Widget):
def init(self):
with ui.VBoxPanel():
ui.Label(text='Flex 0 0 0', style='')
with ui.HBoxPanel(flex=0):
self.b1 = ui.Button(text='Hola', flex=0)
self.b2 = ui.Button(text='Hello world', flex=0)
self.b3 = ui.Button(text='Foo bar', flex=0)
ui.Label(text='Flex 1 0 3')
with ui.HBoxPanel(flex=0):
self.b1 = ui.Button(text='Hola', flex=1)
self.b2 = ui.Button(text='Hello world', flex=0)
self.b3 = ui.Button(text='Foo bar', flex=3)
ui.Label(text='spacing 10 (inter-widget)')
with ui.HBoxPanel(flex=0, spacing=20):
self.b1 = ui.Button(text='Hola', flex=1)
self.b2 = ui.Button(text='Hello world', flex=1)
self.b3 = ui.Button(text='Foo bar', flex=1)
ui.Widget(flex=1)
Interactive BoxLayout example:
from flexx import ui, event
class Example(ui.HBox):
def init(self):
self.b1 = ui.Button(text='Horizontal', flex=0)
self.b2 = ui.Button(text='Vertical', flex=1)
self.b3 = ui.Button(text='Horizontal reversed', flex=2)
self.b4 = ui.Button(text='Vertical reversed', flex=3)
class JS:
@event.connect('b1.mouse_down')
def _to_horizontal(self, *events):
self.orientation = 'h'
@event.connect('b2.mouse_down')
def _to_vertical(self, *events):
self.orientation = 'v'
@event.connect('b3.mouse_down')
def _to_horizontal_rev(self, *events):
self.orientation = 'hr'
@event.connect('b4.mouse_down')
def _to_vertical_r(self, *events):
self.orientation = 'vr'
A classic high level layout:
from flexx import ui
class Content(ui.Widget):
def init(self):
# Here we use BoxLayout, because we care about natural size
with ui.HBox():
ui.Widget(flex=1) # spacer
ui.Button(text='hello')
ui.Widget(flex=1) # spacer
class SideWidget(ui.Label):
CSS = '.flx-SideWidget {background: #aaf; border: 2px solid black;}'
class Example(ui.Widget):
def init(self):
# Here we use BoxPanel, because we define high-level layout
with ui.VBoxPanel():
SideWidget(text='Header', flex=0, base_size=100)
with ui.HBoxPanel(flex=1):
SideWidget(text='Left', flex=0, base_size=100)
Content(flex=1)
SideWidget(text='Right', flex=0, base_size=100)
SideWidget(text='Bottom', flex=0, base_size=100)
-
class
flexx.ui.layouts._box.
BaseBoxLayout
(*init_args, **kwargs)¶ Inherits from:
Layout
Base class for BoxLayout and BoxPanel.
-
orientation
¶ property – The orientation of the child widgets. ‘h’ or ‘v’. Default horizontal. The items can also be reversed using ‘hr’ and ‘vr’.
-
spacing
¶ property – The space between two child elements (in pixels)
-
-
class
flexx.ui.
BoxLayout
(*init_args, **kwargs)¶ Inherits from:
BaseBoxLayout
Layout to distribute space for widgets horizontally or vertically.
This layout implements CSS flexbox. The reference size of each child widget is based on its natural size (e.g. a button’s natural size depends on its text). Further, the minimum and maximum size (set via styling) are taken into account. Extra space is divided according to the flex property of the child widgets.
Also see VBox and HBox for shorthands.
-
padding
¶ property – The empty space around the layout (in pixels).
-
-
class
flexx.ui.
BoxPanel
(*init_args, **kwargs)¶ Inherits from:
BaseBoxLayout
Layout to distribute space for widgets horizontally or vertically.
This layout is implemented using absolute positioning. The reference size of each child widget is based on its
base_size
property. When this value is zero, an attempt is made to measure the natural size of the children, but this is not very reliable. Further, the minimum and maximum size (set via styling) are taken into account. Extra space is divided according to the flex property of the child widgets.The BoxPanel differs from the BoxLayout in that the natural size of widgets is not taken into account. It is therefore more suited for high-level layout or for child widgets that do not have a natural size.
Also see VBoxPanel and HBoxPanel for shorthands.
-
class
flexx.ui.
HBox
(*init_args, **kwargs)¶ Inherits from:
BoxLayout
BoxLayout with horizontal layout. Consider using HBoxPanel if you’re using this for high-level layout.
-
class
flexx.ui.
HBoxPanel
(*init_args, **kwargs)¶ Inherits from:
BoxPanel
BoxPanel with horizontal layout. Consider using HBox if you’re using this for low-level layout and the children have a “natural” size.