Version

Quick search

ToggleButton Behavior

The ToggleButtonBehavior mixin class provides toggle button behavior for Kivy widgets. You can combine this class with other widgets to add specialized on/off state management with optional radio button grouping.

For an overview of behaviors, please refer to the behaviors documentation.

Examples

Basic toggle with visual feedback:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.behaviors import ToggleButtonBehavior

class MyToggle(ToggleButtonBehavior, Label):
    Builder.load_string('''
<MyToggle>:
    canvas.before:
        Color:
            rgb: self.color
            a: 0.25
        Rectangle:
            size: self.size
            pos: self.pos
    ''')

    def on_active(self, instance, value):
        self.color = [0, 1, 0, 1] if value else [1, 1, 1, 1]

class SampleApp(App):
    def build(self):
        return MyToggle()

SampleApp().run()

Radio button group behavior:

from kivy.lang import Builder
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.behaviors import ToggleButtonBehavior


class MyToggle(ToggleButtonBehavior, Label):
    Builder.load_string('''
<MyToggle>:
    canvas.before:
        Color:
            rgb: self.color
            a: 0.25
        Rectangle:
            size: self.size
            pos: self.pos
    ''')

    def on_active(self, instance, value):
        self.color = [0, 1, 0, 1] if value else [1, 1, 1, 1]


class SampleApp(App):
    def build(self):
        layout = BoxLayout()
        for i in range(3):
            btn = MyToggle(
                text=f"Option {i + 1}",
                group="options",
                allow_no_selection=False,
            )
            layout.add_widget(btn)
        return layout


SampleApp().run()

Scoped groups for reusable components:

from kivy.lang import Builder
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.behaviors import ToggleButtonBehavior


class MyToggle(ToggleButtonBehavior, Label):
    Builder.load_string('''
<MyToggle>:
    canvas.before:
        Color:
            rgb: self.color
            a: 0.25
        Rectangle:
            size: self.size
            pos: self.pos
    ''')

    def on_active(self, instance, value):
        self.color = [0, 1, 0, 1] if value else [1, 1, 1, 1]


class ToggleRow(BoxLayout):
    '''Reusable component with scoped group.'''

    def __init__(self, label_prefix="Option", **kwargs):
        super().__init__(**kwargs)
        for i in range(3):
            btn = MyToggle(
                text=f"{label_prefix}, Col {i + 1}",
                # group=("options"),  # Global, not scoped

                # Scoped to this row (ToggleRow instance)
                group=(self, "options"),

                allow_no_selection=False,
                active=i == 0,
            )
            self.add_widget(btn)


class SampleApp(App):
    def build(self):
        layout = BoxLayout(orientation="vertical")
        # Each row has independent "options" group
        layout.add_widget(ToggleRow(label_prefix="Row 1"))
        layout.add_widget(ToggleRow(label_prefix="Row 2"))
        return layout


SampleApp().run()

See ToggleButtonBehavior for details.

class kivy.uix.behaviors.togglebutton.ToggleButtonBehavior(**kwargs)

Bases: kivy.uix.behaviors.button.ButtonBehavior

Mixin to add toggle button behavior to any Kivy widget.

This mixin extends ButtonBehavior to provide persistent on/off state that survives beyond the press/release interaction. It supports grouping multiple toggles together for radio button behavior.

State Management

Unlike the transient pressed property from ButtonBehavior (which is True only during active touch), the active property maintains persistent state:

  • active=True: Button is in “on” state (persists after release)

  • active=False: Button is in “off” state (default)

The active property can be set programmatically or toggled by user interaction. When allow_no_selection is False, attempts to deactivate the last active button in a group will be silently rejected.

Group Behavior

When buttons share a group, they act like radio buttons:

  • Activating one button automatically deactivates others in the group

  • Only one button per group can be active at a time

  • allow_no_selection controls whether all buttons can be deactivated

Without group: Buttons toggle independently With group: Buttons behave as mutually exclusive options

Group Scoping

Groups can be either global or scoped to a specific widget owner:

Global groups (string):

ToggleButton:
    group: "mygroup"  # Shared across entire application

Scoped groups (tuple):

ToggleButton:
    group: (root, "mygroup")  # Scoped to 'root' widget

Scoped groups allow multiple widget hierarchies to use the same group name without interference. This is useful when creating reusable components with internal toggle groups.

Example:

<MyComponent>:
    # These groups won't conflict with other MyComponent instances
    ToggleButton:
        group: (root, "options")
    ToggleButton:
        group: (root, "options")

Events

Inherits all events from ButtonBehavior:
  • on_press(): First touch down

  • on_release(): All touches released

  • on_cancel(): Touch moved outside bounds

Additional property events:

New in version 1.8.0.

Changed in version 3.0.0: - Replaced state OptionProperty with active AliasProperty - Added backward-compatible state alias - Improved group management with automatic cleanup - Added scoped group support via tuple syntax - Replaced get_widgets(groupname) static method with unified get_group() descriptor that works as both instance and class method

on_active(instance, value)

Event handler called when active state changes.

Override this method to respond to state changes.

Parameters:
  • instance – This button instance

  • value – New active state (True/False)