Kivy - Image Button



The Kivy library doesn't have a ready-to-use image button widget. It does have a normal Button and a ToggleButton widget. You can of course use the image files as their background in the normal state or disabled state −

  • background_disabled_down − The background image of the button is a StringProperty, a string containing path to an image file and is used for the default graphical representation when the button is disabled and pressed.

  • background_disabled_normal − Background image of the button is also an image path, used for the default graphical representation when the button is disabled and not pressed.

  • background_down − Background image of the button used as the default graphical representation when the button is pressed.

  • background_normal − Background image of the button used as the default graphical representation when the button is not pressed.

For example, you can use −

B1 = Button(background_normal='images/play.png')

However, to make an image widget function as a clickable button, you need to dfine a custom class based on ButtonBehavior mixin and Image class and override the on_press() method.

ButtonBehavior

In Kivy, the "kivy.uix.behaviors" module defines behavior mixins, which are also called "reusable classes" that provide additional functionality to widgets.

To use of an image as a button, we define a custom class that extends the ButtonBehavior to make it respond to events like on_press or on_touch, so that the image itself can behave as a button.

We use Kivy's Image object to display an image on Kivy window. However, to add button-like behavior to it, we first define a custom class called "imgbtn" that extends the Image as well as the ButtonBehavior classes.

The source property of the Image class is assigned a string which is the path to the image file. We then override the on_press() method.

class imgbtn(ButtonBehavior, Image):
   def __init__(self, **kwargs):
      super(imgbtn, self).__init__(**kwargs)
   def on_press(self):
      print("Button pressed", self.source)
      ImgBtnApp.l1.text=self.source

Example

Let's implement this concept and put four images in the app layout and bind them to a callback. The class to provide button-like functionality to an image is first defined as below −

class imgbtn(ButtonBehavior, Image):
   def __init__(self, **kwargs):
      super(imgbtn, self).__init__(**kwargs)
   def on_press(self):
      ImgBtnApp.l1.text=self.source

We shall now use objects of this class on the application layout to display images and they will raise the on_press event. The source property of the clicked image will be displayed on the label as its text.

from kivy.app import App
from kivy.graphics import *
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.behaviors import ButtonBehavior
from kivy.core.window import Window

Window.size = (720, 400)

class imgbtn(ButtonBehavior, Image):
   def __init__(self, **kwargs):
      super(imgbtn, self).__init__(**kwargs)

   def on_press(self):
      print("Button pressed", self.source)
      ImgBtnApp.l1.text = self.source

class ImgBtnApp(App):
   def build(self):
      main = GridLayout(cols=1)
      ImgBtnApp.l1 = Label(text='Hello', font_size=32)
      main.add_widget(ImgBtnApp.l1)
      root = FloatLayout(size=(Window.width, 100))
      with root.canvas:
         Color(.2, .7, .1, 1)
         Rectangle(pos=root.pos, size=root.size)
      
      self.btn1 = imgbtn(
         source='previous.png', size_hint=(None, None),
         pos_hint={'center_x': .2, 'center_y': .25}
      )
      self.btn2 = imgbtn(
         source='play.png', size_hint=(None, None),
         pos_hint={'center_x': .4, 'center_y': .25}
      )
      self.btn3 = imgbtn(
         source='pause.png', size_hint=(None, None),
         pos_hint={'center_x': .6, 'center_y': .25}
      )
      self.btn4 = imgbtn(
         source='stop.png', size_hint=(None, None),
         pos_hint={'center_x': .8, 'center_y': .25}
      )
      root.add_widget(self.btn1)
      root.add_widget(self.btn2)
      root.add_widget(self.btn3)
      root.add_widget(self.btn4)
      
      main.add_widget(root)
      return main
      
ImgBtnApp().run()

Output

Run the code and click each of the four buttons one by one.

Kivy Image Button
Advertisements