Skip to content

The batteries included

PyTermGUI provides a selection of widgets you can drop straight into your projects. Looking at the widgets submodule's contents can help illuminate you on the exact selection, but this page describes the most commonly used ones.

A note about auto

Some widgets below will have an Auto syntax field shown. The format shown can be used by the auto function to generate widgets from Python datatypes. This function is conveniently called within Container and all its subclasses (Splitter, Window, Collapsible & more) to let you easily create widgets with minimal imports.

For example:

from pytermgui import Container

container = Container(
    "[bold accent]This is my example",
    "",
    "[surface+1 dim italic]It is very cool, you see",
    "",
    {"My first label": ["Some button"]},
    {"My second label": [False]},
    "",
    ("Left side", "Middle", "Right side"),
    "",
    ["Submit button"]
)

...is functionally identical to:

from pytermgui import Container, Label, Splitter, Button, Checkbox

container = Container(
    Label("[bold accent]This is my example"),
    Label(""),
    Label("[surface+1 dim italic]It is very cool, you see"),
    Label(""),
    Splitter(
        Label("My first label", parent_align=0),
        Button("Some button", parent_align=2),
    ),
    Splitter(
        Label("My second label"),
        Checkbox(),
    ),
    Label(""),
    Splitter(Label("Left side"), Label("Middle"), Label("Right side")),
    Label(""),
    Button("Submit button"),
)

You can use whichever you find more convenient and readable.


Label

A simple widget meant to display text. Supports line breaking and styling using both markup and simple callables.

Auto syntax: "label_value"

Chars: N/A

Styles:

  • value: Applies to the text within the label.

    Default: No styling.


Container

A widget to display other widgets, stacked vertically. It may display a box around said widgets as well, using the border and corner characters.

Auto syntax: N/A

Chars:

  • border: A list[str] in the order left, top, right, bottom that makes up the borders of the outer box.
  • corner: A list[str] in the order top_left, top_right, bottom_right, bottom_left that makes up the corners of the outer box.

Styles:

  • border: Applies to all border characters of the outer box.

    Default: surface.

  • corner: Applies to all corner characters of the outer box.

    Default: surface.

  • fill: Applies to the filler characters used for padding.

    Default: background.


Splitter

Similar to Container, but displays widgets stacked horizontally instead. Each widget is separated by the separator character set.

Auto syntax:

  • (widget1, widget2, ...)
  • {widget_aligned_left: widget_aligned_right}

Chars:

  • separator: The str used to join the contained widgets.

Styles:

  • separator: Applies to the separator character.

    Default: surface.


Collapsible

A widget that hides or shows whatever other widgets it is given. It will always display its "trigger", the Button used to collapse or expand its content.

Auto syntax: N/A

Chars:

  • See Container.

Styles:

  • See Container.

Window

An extended version of Container, used in the window_manager context.

Auto syntax: N/A

Chars:

See Container.

Styles:

Same as Container, but expanded with:

  • border_focused: Analogous to border, but only applied when the window is focused.

    Default: surface.

  • corner_focused: Analogous to corner, but only applied when the window is focused.

    Default: surface.

  • border_blurred: Analogous to border, but only applied when the window is NOT focused.

    Default: surface-2.

  • corner_blurred: Analogous to corner, but only applied when the window is NOT focused.

    Default: surface-2.


Button

Something clickable. All widgets can be made clickable by defining an on_click method, but this widget looks the part as well.

Auto syntax:

  • ["button_label", button_callback]

Chars:

  • delimiter: a list[str] in the order left, right. Each character will be placed at the respective sides of the label.

Styles:

All styles here apply to the full label, including the left and right hand side delimiters.

  • label: Applies in the normal state (e.g. no hover, click applied).

    Default: @surface dim.

  • highlight: Applies when the button is interacted with.

    Default: @surface+1 dim.


KeyboardButton

Much like button, but has a default binding applied to it. This binding is also reflected in its label.

Auto syntax: N/A

Chars:

  • All Button chars
  • bracket: Used to wrap the button's bound key.

Styles:

  • See Button.

Checkbox

A simple check box, you know the drill.

Auto syntax:

  • [bool_default, callback_method]

Chars:

  • delimiter: Wraps the checkbox's value
  • checked: The character inserted between delimiters when the widget is checked.
  • unchecked: The character inserted between delimiters when the widget is unchecked.

Styles:

  • See Button.

Toggle

A button that toggles its label between the two given values.

Auto syntax:

  • [("label_1", "label_2"), callback_method]

Chars:

  • See Button.

Styles:

  • See Button.

Selecting one or more options

Checkbox widgets can be grouped when an application needs to select from a configured list of strings. The widget's checked argument sets its default state, and its checked and unchecked characters provide the visual indication.

Selecting exactly one option

For radio-button behavior, define a container that unchecks the other widgets when an option is selected. Its value property reads the selected string directly from the checkbox states, so no separate application state is needed.

import pytermgui as ptg


class SingleSelect(ptg.Container):
    def __init__(self, options, default, **attrs):
        if default not in options:
            raise ValueError("default must be one of the options")

        self.options = list(options)
        self._checkboxes = []
        rows = []

        for index, option in enumerate(self.options):
            checkbox = ptg.Checkbox(
                lambda checked, index=index: self._select(index, checked),
                checked=option == default,
            )
            self._checkboxes.append(checkbox)
            rows.append(ptg.Splitter(ptg.Label(option), checkbox))

        super().__init__(*rows, **attrs)

    def _select(self, index, checked):
        if not checked:
            # Keep the current option selected until another is chosen.
            self._checkboxes[index].toggle(run_callback=False)
            return

        for other_index, checkbox in enumerate(self._checkboxes):
            if other_index != index and checkbox.checked:
                checkbox.toggle(run_callback=False)

    @property
    def value(self):
        """Return the selected option as a string."""
        selected = next(
            index for index, checkbox in enumerate(self._checkboxes)
            if checkbox.checked
        )
        return self.options[selected]


size = SingleSelect(["small", "medium", "large"], default="medium")

Add size to a window or another container. Reading size.value returns "small", "medium", or "large"; before any interaction it returns the configured default, "medium".

Selecting multiple options

For multiple selection, each checkbox can toggle independently. The value property returns the strings whose checkboxes are currently checked, in their configured order.

import pytermgui as ptg


class MultiSelect(ptg.Container):
    def __init__(self, options, defaults=(), **attrs):
        self.options = list(options)
        self._checkboxes = []
        rows = []

        for option in self.options:
            checkbox = ptg.Checkbox(checked=option in defaults)
            self._checkboxes.append(checkbox)
            rows.append(ptg.Splitter(ptg.Label(option), checkbox))

        super().__init__(*rows, **attrs)

    @property
    def value(self):
        """Return the selected options as a list of strings."""
        return [
            option
            for option, checkbox in zip(self.options, self._checkboxes)
            if checkbox.checked
        ]


colors = MultiSelect(
    ["red", "green", "blue"],
    defaults=["red", "blue"],
)

Add colors to a window or another container. Each click changes the visual state; clicking a checked option again deselects it. Before any interaction, colors.value returns ["red", "blue"].


Slider

A widget to display and/or control a floating point value.

Auto syntax: N/A

Chars:

  • cursor: The character placed at the end of the filled section. If nothing is given, rail is used.
  • rail: Used to fill up the width of the slider, colored as applicable.
  • delimiter: Wraps the rail characters on both sides.

Styles:

  • cursor: Applied to the cursor character, or the last character of the rail.

    Default: primary.

  • filled: Applied to the filled section of the rail if the slider is not selected.

    Default: surface+1.

  • filled_selected: Applied to the filled section of the rail if the slider is selected.

    Default: primary.

  • unfilled: Applied to the unfilled section of the rail if the slider is not selected.

    Default: surface-1.

  • unfilled_selected: Applied to the unfilled section of the rail if the slider is selected.

    Default: surface.


InputField

A field to display input. Should be used in a context that sends it keyboard inputs, such as WindowManager.

Auto syntax: N/A

Chars: N/A

Styles:

  • value: Applies to the text of the input field.

    Default: No styling.

  • prompt: Applies to the string displayed before the field's value, controlled by the prompt parameter.

    Default: surface+2

  • cursor: Applies to the field's cursor.

    Default: @primary dim #auto


PixelMatrix

A customizable matrix of unicode pixels. With some image decoding, it can be used to display low-resolution pictures.

Auto syntax: N/A

Chars: N/A

Styles: N/A


DensePixelMatrix

Similar to PixelMatrix, but instead of using two unicode block characters per pixel, it uses either the upper or lower half of one. Allows for higher resolution pictures!

Auto syntax: N/A

Chars: See PixelMatrix

Styles: See PixelMatrix