Kivy - Bubble



Kivy framework consists of a Bubble widget that acts as a small popup menu with an arrow on any one side of its contents. The direction of arrow can be configured as required. You can place it by setting its relative position of the "arrow_pos" property.

Contents of the bubble are placed in a "BubbleContent" object, a subclass of BoxLayout. One or more BubbleButtons can be placed either horizontally or vertically. Although it is recommended use BubbleButtons, you can add any widget in the bubble's content.

Kivy Bubble

The classes Bubble, BubbleContent, and BubbleButton are defined in kivy.uix.bubble module.

from from kivy.uix.bubble import Bubble

The following properties of the Bubble class help in customizing the appearance and behaviour of the Bubble menu −

  • arrow_color − Arrow color, in the format (r, g, b, a). To use it you have to set arrow_image first, defaults to [1, 1, 1, 1].

  • arrow_image − Image of the arrow pointing to the bubble.

  • arrow_margin − Automatically computed margin that the arrow widget occupies in x and y direction in pixel.

  • arrow_pos − Specifies the position of the arrow as per one of the predefined values: left_top, left_mid, left_bottom top_left, top_mid, top_right right_top, right_mid, right_bottom bottom_left, bottom_mid, bottom_right. The default value is 'bottom_mid'.

  • content − This is the object where the main content of the bubble is held.

  • show_arrow − Indicates whether to show arrow. Default is True.

  • BubbleButton − A button intended for use in a BubbleContent widget. Instead of this, you can use a "normal" button, but it will may look good unless the background is changed.

  • BubbleContent − A styled BoxLayout that can be used as the content widget of a Bubble.

The following schematic "kv" language script is used to build a simple Bubble object −

Bubble:
   BubbleContent:
      BubbleButton:
         text: 'Button 1'
      BubbleButton:
         text: 'Button 2'

Just as in case of a normal Button, we can bind a BubbleButton to a callback for its "on_press" event.

Example

When the following code is executed, it presents a normal button. When clicked, a Bubble menu pops up with three BubbleButtons. Each of these BubbleButtons invoke a pressed() callback method that reads the button's caption and prints it on the console.

We use the following "kv" language script to assemble the Bubble menu. A class named as "Choices" has been defined that subclasses the "kivy.uix.bubble.Bubble" class.

class Choices(Bubble):
   def pressed(self, obj):
      print ("I like ", obj.text)
      self.clear_widgets()

The class has pressed() instance method, invoked by each BubbleButton.

Here is the "kv" script −

<Choices>
   size_hint: (None, None)
   size: (300, 150)
   pos_hint: {'center_x': .5, 'y': .6}
   canvas:
      Color:
         rgb: (1,0,0)
      Rectangle:
         pos:self.pos
         size:self.size
   BubbleContent:
      BubbleButton:
         text: 'Cricket'
         size_hint_y: 1
         on_press:root.pressed(self)
      BubbleButton:
         text: 'Tennis'
         size_hint_y: 1
         on_press:root.pressed(self)
      BubbleButton:
         text: 'Hockey'
         size_hint_y: 1
         on_press:root.pressed(self)

BoxLayout widget acts as the root widget for the main application window and consists of a Button and a label. The "on_press" event invokes the "show_bubble()" method that pops up the bubble.

class BubbleTest(FloatLayout):
   def __init__(self, **temp):
      super(BubbleTestApp, self).__init__(**temp)
      self.bubble_button = Button(
         text ='Your favourite Sport',
         pos_hint={'center_x':.5, 'center_y':.5},
         size_hint=(.3, .1),size=(300, 100)
      )
      self.bubble_button.bind(on_release = self.show_bubble)
      self.add_widget(self.bubble_button)

   def show_bubble(self, *arg):
      self.obj_bub = Choices()
      self.add_widget(self.obj_bub)

The driver App class code is as below −

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.bubble import Bubble
from kivy.properties import ObjectProperty
from kivy.core.window import Window

Window.size = (720,400)

class MybubbleApp(App):
   def build(self):
      return BubbleTest()

MybubbleApp().run()

Output

The application shows a button at the center of the main window. When clicked, you should see the bubble menu above it.

Kivy Bubble Menu

Every time you click any of the options in the bubble, the console shows the result, and hides the bubble.

I like Tennis
I like Hockey
Advertisements