Some components can contain other components. We call these containers. (A Form is also a container.)
The best way to see how each container behaves is to experiment - drop a container into a Form and drop several TextAreas into it. Play around and see how many ways you can arrange things.
Controlling Containers from code
You can add any component to a container in Python by calling the method
For example, the following code sets up an XYPanel that is 400x400 pixels, adds it to the current Form, and then adds two components to it:
xyp = XYPanel(width=400, height=400) self.add_component(xyp) lbl = Label(text="Hello") xyp.add_component(lbl, x=10, y=10) btn = Button(text="Click me!") xyp.add_component(btn, x=10, y=100)
To remove a component from its parent container, call its
Alternatively, you can remove all components from a particular container by calling
clear() on the container:
To get a list of all components currently in the container, call
components = my_container.get_components() print("%d components" % len(components))
To raise an event on all children of a component without referencing the children directly, call
For more on adding, removing and getting components within containers, see the Containers overview.
Container Properties are properties that control the relationship between a component and the container it is in; the argument names and their meanings are specific to the type of container. They are visible in the Properties panel in the Anvil Editor.
They can also be passed as keyword arguments to
add_component. For example, Data Row Panels inside a Data Grid have a
pinned property that determines whether the Data Row Panel is visible on every page of a paginated Data Grid:
This container allows you to drag and drop components into rows and columns. The ColumnPanel is the default layout for Anvil Forms.
Components added at runtime using the
add_component method will each be added to their own row.
In this respect, the ColumnPanel behaves the same as the LinearPanel at runtime. There are no special arguments
to pass to
LinearPanel, the ColumnPanel will expand to fit its contents.
Components in a ColumnPanel have several container properties, which can be set in the Properties dialog:
True, this row of components will stretch to the full width of the screen. (Default:
row_background: Set to a CSS color for the background of this row. Note that the background stretches to the full with of the browser. (Default:
cp = ColumnPanel(background='yellow') # Add a TextBox to the Column Panel and give it the full_width_row container property cp.add_component(TextBox(text='enter some text', full_width_row=True))
This container allows you to display components in lines with wrapping. Each component will only take up the horizontal space that it needs.
Some components, like Buttons, dictate their own width when placed inside FlowPanels, based on their content. For components like TextBoxes, that don’t have a width specified by their content, you can drag the handle to set the width you require.
fp = FlowPanel(align="center", spacing="small") # A button determines its own width fp.add_component(Button(text="Click me")) # You set the width of a TextBox explicitly fp.add_component(TextBox(), width=100)
If a component doesn’t fit on the same row as the previous component, it will wrap onto a new line.
To control the space between components, set the
spacing property of the FlowPanel.
Like many other containers, the FlowPanel will expand vertically to fit its contents.
By default, components are added at the end of a FlowPanel. If you pass an
add_component(), the component will be inserted at the specified position.
Index 0 is the first element in the panel, 1 is the second, etc.
fp = FlowPanel() fp.add_component(Button(text="Button")) # Display the label to the left of the button: fp.add_component(Label(text="Click here:"), index=0)
For full documentation on the DataRowPanel, see the section on Data Grids
The DataRowPanel is a special Anvil container, designed to work inside the DataGrid component. In particular, DataRowPanels inherit the column-based layout of their parent DataGrids, so they can arrange their child components appropriately. There are two main features of DataRowPanels that differentiate them from other Anvil containers:
- DataRowPanels have a ‘slot’ for each column of their parent Data Grid, meaning other Anvil components can be dropped into particular columns. They also behave like LinearPanels, in that components placed outside the column-specific slots will take up the full width of the container. This is useful for section headers and other advanced layouts.
- DataRowPanels can automatically display data in the column-based layout of their parent DataGrid. This is done by setting the
itemproperty of the DataRowPanel to a dictionary with the same keys as the
data_keysof the Data Grid columns.
This container arranges its child components vertically, each filling the whole width of the panel by default.
It doesn’t require any extra arguments for
add_component: each component is added to the bottom of the LinearPanel.
lp = LinearPanel() lp.add_component(Label(text="Hello")) lp.add_component(Button(text="Click me"))
The LinearPanel will expand vertically to fit its contents.
By default, components are added at the end of a LinearPanel.
If you add an
index parameter to the
add_component() call, the component will be added at that index. Index 0 is the first element in the panel, 1 is the second, etc.
# self.linear_panel_1 is a LinearPanel lp.add_component(Button(text="Button")) # This label will be added above the Button. lp.add_component(Label(text="Label"), index=0)
This container allows its child components to be placed at a specific position inside the container. Positions are measured in pixels from the top-left of the panel. To help with positioning components, you can get the width of an
XYPanel by calling the
x: How far across the component is from the left-hand edge
y: How far down the component is from the top edge
xy_panel = XYPanel(width=400, height=400) btn = Button(text="Click me!") xy_panel.add_component(btn, x=10, y=100)
This container lays out components on a grid. Each row has twelve columns, and a component can span multiple columns. Components occupying the same columns in different rows will be aligned.
gp = GridPanel() gp.add_component(Label(text="Name:"), row="MyRow", col_xs=0, width_xs=2) gp.add_component(TextBox(), row="MyRow", col_xs=2, width_xs=6) gp.add_component(Button(text="Submit"), row="MyOtherRow", col_xs=3, width_xs=2)
row: The name of the row to which this component will be added. If this is the first component with this row name, a new row will be created at the bottom of the GridPanel.
col_xs: What’s the first column this component occupies? (0-11, default 0)
width_xs: How many columns does this component occupy? (1-12, default 12)