Skip to content

Gtk.FlowBox

class — extends Widget, Accessible, Buildable, ConstraintTarget, Orientable

Puts child widgets in a reflowing grid.

<picture> <source srcset="flow-box-dark.png" media="(prefers-color-scheme: dark)"> <img alt="An example GtkFlowBox" src="flow-box.png"> </picture>

For instance, with the horizontal orientation, the widgets will be arranged from left to right, starting a new row under the previous row when necessary. Reducing the width in this case will require more rows, so a larger height will be requested.

Likewise, with the vertical orientation, the widgets will be arranged from top to bottom, starting a new column to the right when necessary. Reducing the height will require more columns, so a larger width will be requested.

The size request of a GtkFlowBox alone may not be what you expect; if you need to be able to shrink it along both axes and dynamically reflow its children, you may have to wrap it in a GtkScrolledWindow to enable that.

The children of a GtkFlowBox can be dynamically sorted and filtered.

Although a GtkFlowBox must have only GtkFlowBoxChild children, you can add any kind of widget to it via FlowBox.insert, and a GtkFlowBoxChild widget will automatically be inserted between the box and the widget.

Also see ListBox.

Shortcuts and Gestures

The following signals have default keybindings:

CSS nodes

flowbox
├── flowboxchild
│   ╰── <child>
├── flowboxchild
│   ╰── <child>
╰── [rubberband]

GtkFlowBox uses a single CSS node with name flowbox. GtkFlowBoxChild uses a single CSS node with name flowboxchild. For rubberband selection, a subnode with name rubberband is used.

Accessibility

GtkFlowBox uses the AccessibleRole.grid role, and GtkFlowBoxChild uses the AccessibleRole.grid_cell role.

Constructors

new

@classmethod
def new(cls) -> Widget

Creates a GtkFlowBox.

Methods

append

def append(self, child: Widget) -> None

Adds child to the end of self.

If a sort function is set, the widget will actually be inserted at the calculated position.

See also: FlowBox.insert.

Parameters:

  • child — the GtkWidget to add

bind_model

def bind_model(self, model: Gio.ListModel | None, create_widget_func: FlowBoxCreateWidgetFunc) -> None

Binds model to box.

If box was already bound to a model, that previous binding is destroyed.

The contents of box are cleared and then filled with widgets that represent items from model. box is updated whenever model changes. If model is None, box is left empty.

It is undefined to add or remove widgets directly (for example, with FlowBox.insert) while box is bound to a model.

Note that using a model is incompatible with the filtering and sorting functionality in GtkFlowBox. When using a model, filtering and sorting should be implemented by the model.

Parameters:

  • model — the GListModel to be bound to box
  • create_widget_func — a function that creates widgets for items

get_activate_on_single_click

def get_activate_on_single_click(self) -> bool

Returns whether children activate on single clicks.

get_child_at_index

def get_child_at_index(self, idx: int) -> FlowBoxChild | None

Gets the nth child in the box.

Parameters:

  • idx — the position of the child

get_child_at_pos

def get_child_at_pos(self, x: int, y: int) -> FlowBoxChild | None

Gets the child in the (x, y) position.

Both x and y are assumed to be relative to the origin of box.

Parameters:

  • x — the x coordinate of the child
  • y — the y coordinate of the child

get_column_spacing

def get_column_spacing(self) -> int

Gets the horizontal spacing.

get_homogeneous

def get_homogeneous(self) -> bool

Returns whether the box is homogeneous.

get_max_children_per_line

def get_max_children_per_line(self) -> int

Gets the maximum number of children per line.

get_min_children_per_line

def get_min_children_per_line(self) -> int

Gets the minimum number of children per line.

get_row_spacing

def get_row_spacing(self) -> int

Gets the vertical spacing.

get_selected_children

def get_selected_children(self) -> list[FlowBoxChild]

Creates a list of all selected children.

get_selection_mode

def get_selection_mode(self) -> SelectionMode

Gets the selection mode of box.

insert

def insert(self, widget: Widget, position: int) -> None

Inserts the widget into box at position.

If a sort function is set, the widget will actually be inserted at the calculated position.

If position is -1, or larger than the total number of children in the box, then the widget will be appended to the end.

Parameters:

  • widget — the GtkWidget to add
  • position — the position to insert child in

invalidate_filter

def invalidate_filter(self) -> None

Updates the filtering for all children.

Call this function when the result of the filter function on the box is changed due to an external factor. For instance, this would be used if the filter function just looked for a specific search term, and the entry with the string has changed.

invalidate_sort

def invalidate_sort(self) -> None

Updates the sorting for all children.

Call this when the result of the sort function on box is changed due to an external factor.

prepend

def prepend(self, child: Widget) -> None

Adds child to the start of self.

If a sort function is set, the widget will actually be inserted at the calculated position.

See also: FlowBox.insert.

Parameters:

  • child — the GtkWidget to add

remove

def remove(self, widget: Widget) -> None

Removes a child from box.

Parameters:

  • widget — the child widget to remove

remove_all

def remove_all(self) -> None

Removes all children from box.

This function does nothing if box is backed by a model.

select_all

def select_all(self) -> None

Select all children of box, if the selection mode allows it.

select_child

def select_child(self, child: FlowBoxChild) -> None

Selects a single child of box, if the selection mode allows it.

Parameters:

  • child — a child of box

selected_foreach

def selected_foreach(self, func: FlowBoxForeachFunc) -> None

Calls a function for each selected child.

Note that the selection cannot be modified from within this function.

Parameters:

  • func — the function to call for each selected child

set_activate_on_single_click

def set_activate_on_single_click(self, single: bool) -> None

If single is True, children will be activated when you click on them, otherwise you need to double-click.

Parameters:

  • singleTrue to emit child-activated on a single click

set_column_spacing

def set_column_spacing(self, spacing: int) -> None

Sets the horizontal space to add between children.

Parameters:

  • spacing — the spacing to use

set_filter_func

def set_filter_func(self, filter_func: FlowBoxFilterFunc | None = ...) -> None

By setting a filter function on the box one can decide dynamically which of the children to show.

For instance, to implement a search function that only shows the children matching the search terms.

The filter_func will be called for each child after the call, and it will continue to be called each time a child changes (via FlowBoxChild.changed) or when FlowBox.invalidate_filter is called.

Note that using a filter function is incompatible with using a model (see FlowBox.bind_model).

Parameters:

  • filter_func — callback that lets you filter which children to show

set_hadjustment

def set_hadjustment(self, adjustment: Adjustment) -> None

Hooks up an adjustment to focus handling in box.

The adjustment is also used for autoscrolling during rubberband selection. See ScrolledWindow.get_hadjustment for a typical way of obtaining the adjustment, and FlowBox.set_vadjustment for setting the vertical adjustment.

The adjustments have to be in pixel units and in the same coordinate system as the allocation for immediate children of the box.

Parameters:

  • adjustment — an adjustment which should be adjusted when the focus is moved among the descendents of container

set_homogeneous

def set_homogeneous(self, homogeneous: bool) -> None

Sets whether or not all children of box are given equal space in the box.

Parameters:

  • homogeneousTrue to create equal allotments, False for variable allotments

set_max_children_per_line

def set_max_children_per_line(self, n_children: int) -> None

Sets the maximum number of children to request and allocate space for in box’s orientation.

Setting the maximum number of children per line limits the overall natural size request to be no more than n_children children long in the given orientation.

Parameters:

  • n_children — the maximum number of children per line

set_min_children_per_line

def set_min_children_per_line(self, n_children: int) -> None

Sets the minimum number of children to line up in box’s orientation before flowing.

Parameters:

  • n_children — the minimum number of children per line

set_row_spacing

def set_row_spacing(self, spacing: int) -> None

Sets the vertical space to add between children.

Parameters:

  • spacing — the spacing to use

set_selection_mode

def set_selection_mode(self, mode: SelectionMode | int) -> None

Sets how selection works in box.

Parameters:

  • mode — the new selection mode

set_sort_func

def set_sort_func(self, sort_func: FlowBoxSortFunc | None = ...) -> None

By setting a sort function on the box, one can dynamically reorder the children of the box, based on the contents of the children.

The sort_func will be called for each child after the call, and will continue to be called each time a child changes (via FlowBoxChild.changed) and when FlowBox.invalidate_sort is called.

Note that using a sort function is incompatible with using a model (see FlowBox.bind_model).

Parameters:

  • sort_func — the sort function

set_vadjustment

def set_vadjustment(self, adjustment: Adjustment) -> None

Hooks up an adjustment to focus handling in box.

The adjustment is also used for autoscrolling during rubberband selection. See ScrolledWindow.get_vadjustment for a typical way of obtaining the adjustment, and FlowBox.set_hadjustment for setting the horizontal adjustment.

The adjustments have to be in pixel units and in the same coordinate system as the allocation for immediate children of the box.

Parameters:

  • adjustment — an adjustment which should be adjusted when the focus is moved among the descendents of container

unselect_all

def unselect_all(self) -> None

Unselect all children of box, if the selection mode allows it.

unselect_child

def unselect_child(self, child: FlowBoxChild) -> None

Unselects a single child of box, if the selection mode allows it.

Parameters:

  • child — a child of box

Properties

accept_unpaired_release

accept_unpaired_release: bool  # read/write

Whether to accept unpaired release events.

activate_on_single_click

activate_on_single_click: bool  # read/write

Determines whether children can be activated with a single click, or require a double-click.

column_spacing

column_spacing: int  # read/write

The amount of horizontal space between two children.

homogeneous

homogeneous: bool  # read/write

Determines whether all children should be allocated the same size.

max_children_per_line

max_children_per_line: int  # read/write

The maximum amount of children to request space for consecutively in the given orientation.

min_children_per_line

min_children_per_line: int  # read/write

The minimum number of children to allocate consecutively in the given orientation.

Setting the minimum children per line ensures that a reasonably small height will be requested for the overall minimum width of the box.

row_spacing

row_spacing: int  # read/write

The amount of vertical space between two children.

selection_mode

selection_mode: SelectionMode | int  # read/write

The selection mode used by the flow box.

Signals

activate-cursor-child

def on_activate_cursor_child(self) -> None: ...

Emitted when the user activates the box.

This is a keybinding signal.

child-activated

def on_child_activated(self, child: FlowBoxChild) -> None: ...

Emitted when a child has been activated by the user.

move-cursor

def on_move_cursor(self, step: MovementStep, count: int, extend: bool, modify: bool) -> bool: ...

Emitted when the user initiates a cursor movement.

This is a keybinding signal. Applications should not connect to it, but may emit it with g_signal_emit_by_name() if they need to control the cursor programmatically.

The default bindings for this signal come in two variants, the variant with the Shift modifier extends the selection, the variant without the Shift modifier does not. There are too many key combinations to list them all here.

  • <kbd>←</kbd>, <kbd>→</kbd>, <kbd>↑</kbd>, <kbd>↓</kbd> move by individual children
  • <kbd>Home</kbd>, <kbd>End</kbd> move to the ends of the box
  • <kbd>PgUp</kbd>, <kbd>PgDn</kbd> move vertically by pages

select-all

def on_select_all(self) -> None: ...

Emitted to select all children of the box, if the selection mode permits it.

This is a keybinding signal.

The default bindings for this signal is <kbd>Ctrl</kbd>-<kbd>a</kbd>.

selected-children-changed

def on_selected_children_changed(self) -> None: ...

Emitted when the set of selected children changes.

Use FlowBox.selected_foreach or FlowBox.get_selected_children to obtain the selected children.

toggle-cursor-child

def on_toggle_cursor_child(self) -> None: ...

Emitted to toggle the selection of the child that has the focus.

This is a keybinding signal.

The default binding for this signal is <kbd>Ctrl</kbd>-<kbd>Space</kbd>.

unselect-all

def on_unselect_all(self) -> None: ...

Emitted to unselect all children of the box, if the selection mode permits it.

This is a keybinding signal.

The default bindings for this signal is <kbd>Ctrl</kbd>-<kbd>Shift</kbd>-<kbd>a</kbd>.