Kivy - Toggle Button



The ToggleButton widget in the Kivy framework behaves somewhat like a Checkbox widget. It also has a binary property called state which has two possible values − normal or down.

The ToggleButton is a button with the difference that when a button is pressed, the pressed and released events occur almost simultaneously; whereas when a toggle button is pressed, the down state persists till it is again pressed to bring to normal state.

Kivy Toggle Button

The two states of a ToggleButton have a distinct background color for each state, which may be customized by assigning value to "background_normal" and "background_down" properties.

The ToggleButton class inherits Button class and the ToggleButtonBehavior mixin. It is defined in kivy.uix.togglebutton module

from kivy.uix.togglebutton import ToggleButton
toggle = ToggleButton(**kwargs)

Just like the Checkbox, multiple ToggleButton objects can be grouped together. By default, each toggle button can be used to represent two states (such as ON/OFF in Switch widget). But, if multiple toggle buttons have the same value for group property, only one in the group will have down state. When one of the grouped buttons is down, the rest will be automatically set to normal.

btn1 = ToggleButton(text='Male', group='sex',)
btn2 = ToggleButton(text='Female', group='sex', state='down')

In this case, the two buttons belong to the same group, and hence only one of them can be in down state at a time.

Since it inherits Button class, we can process the on_press event on a toggle button. Additionally, the "on_state" event can be bound to its state property.

Example 1

The following code puts three Toggle Buttons that are not grouped. Hence, each of them can be put to normal or down state. In the example below, these toggle buttons represent the subjects of interest to be chosen by the user.

self.button1 = ToggleButton(text ="Sports", font_size=32)
self.button2 = ToggleButton(text='Music', font_size=32)
self.button3 = ToggleButton(text='Travel', font_size=32)

They are bound to callbacks to identify the state of each button

self.button1.bind(on_press=self.btn1pressed)
self.button2.bind(on_press=self.btn2pressed)
self.button3.bind(on_press=self.btn3pressed)

Each callback method checks if the state is down, and accordingly updates the label text.

def btn1pressed(self, instance):
   if instance.state=='down':
      self.sports='Sports'
   else:
      self.sports=''
   self.l1.text="{} {} {}".format(self.sports, self.music, self.travel)

The complete code for this exercise is given below −

from kivy.app import App
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window

Window.size = (720, 350)

class toggledemoapp(App):
   def build(self):
      self.sports = self.music = self.travel = ''

      layout = GridLayout(cols=1, padding=10)
      box = BoxLayout(orientation='horizontal')

      lbl = Label(text="My Interests", font_size=40)
      layout.add_widget(lbl)

      self.l1 = Label(
         text='Choose One or More', font_size=32,
         color=[.8, .6, .4, 1]
      )
      layout.add_widget(self.l1)
      
      self.button1 = ToggleButton(text="Sports", font_size=32)
      self.button2 = ToggleButton(text='Music', font_size=32)
      self.button3 = ToggleButton(text='Travel', font_size=32)

      self.button1.bind(on_press=self.btn1pressed)
      self.button2.bind(on_press=self.btn2pressed)
      self.button3.bind(on_press=self.btn3pressed)

      box.add_widget(self.button1)
      box.add_widget(self.button2)
      box.add_widget(self.button3)

      layout.add_widget(box)
      return layout

   def btn1pressed(self, instance):
      if instance.state == 'down':
         self.sports = 'Sports'
      else:
         self.sports = ''
      self.l1.text = "{} {} {}".format(self.sports, self.music, self.travel)

   def btn2pressed(self, instance):
      if instance.state == 'down':
         self.music = 'Music'
      else:
         self.music = ''
      self.l1.text = "{} {} {}".format(self.sports, self.music, self.travel)

   def btn3pressed(self, instance):
      if instance.state == 'down':
         self.travel = 'Travel'
      else:
         self.travel = ''
      self.l1.text = "{} {} {}".format(self.sports, self.music, self.travel)

toggledemoapp().run()

Output

The application opens with all the buttons in normal state. Try and put any of them in "down".

Kivy Toggle Button Choose

Example 2

The following example assembles the labels and toggle buttons in similar layout as the above image shows, except that the toggle buttons are now grouped together.

We shall use a "kv" script to design the app layout. The Mylayout class is used as the root of the app, and uses GridLayout as its base.

class Mylayout(GridLayout):
   def callback(self, *args):
      print (args[0].text)
      self.ids.l1.text=args[0].text

class togglegroupapp(App):
   def build(self):
      return Mylayout()
      
togglegroupapp().run()

Here is the "kv" language script. It puts three toggle buttons in a horizontal box, which in tur is a part of the one-column grid layout. All the buttons have same value 'branch' of group property, and are bound to the callback() method of MyLayout class above. The callback() method puts the caption of the button that caused the on_press event, on the label to show which branch has the user chosen.

<Mylayout>:
   size: root.width, root.height
   cols:1
   Label:
      text:"Which is your Engineering branch?"
      font_size:40
   Label:
      id:l1
      text: 'Choose Any One'
      font_size:32
      color:[.8,.6,.4,1]
   BoxLayout:
      orientation:'horizontal'
      ToggleButton:
         text : "Electronics"
         font_size : 32
         group:'branch'
         on_press:root.callback(*args)
      ToggleButton:
         text:'Mechanical'
         font_size:32
         group:'branch'
         on_press:root.callback(*args)
      ToggleButton:
         text:'Comp.Sci'
         font_size:32
         group:'branch'
         on_press:root.callback(*args)

Output

Run the program and experiment with the button states as shown below −

Kivy Toggle Button Branch
Advertisements