”;
A Button, as most of the GUI widgets in Kivy, is programmed to respond to specific types of events. A Button processes the following event types −
-
on_press − Triggered when the button is pressed.
-
on_release − Triggered when the button is released.
-
on_touch_down − Triggered when a touch event starts on the button.
-
on_touch_up − Triggered when a touch event ends on the button.
Kivy”s EventDispatcher class provides a bind() method which is responsible for delegating the event to a certain callback function for processing.
EventDispatcher.bind(self, **kwargs)
Button (as does each Kivy widget) inherits this method. Hence, we can bind a Button object to any callback eventhandler function. You can also bind a property to a callback.
Binding Event
Given below is a typical way to bind the on_press event of a button is bound to a function −
def callback(instance): print(''The button is being pressed'') btn1 = Button(text=''Hello world'') btn1.bind(on_press=callback)
Example
In the following example, we have put two buttons inside FloatLayout. The “on_press” event of each button is bound to the callback() method.
The reference of the button on which the “on_press” event occurred is passed to the callback() method, so that we can identify the caption of the button pressed.
from kivy.app import App from kivy.uix.button import Button from kivy.config import Config from kivy.uix.floatlayout import FloatLayout # Configuration Config.set(''graphics'', ''width'', ''720'') Config.set(''graphics'', ''height'', ''400'') Config.set(''graphics'', ''resizable'', ''1'') class ButtonApp(App): def on_button_press(self, instance): print("{} Button pressed!".format(instance.text)) def build(self): flo = FloatLayout() btn1 = Button(text= ''Hello World'', background_color= [1,0,0,1], font_size= 20, underline= True, size_hint= (.4, .25), pos_hint= {''center_x'':.5, ''center_y'':.8}) btn1.bind(on_press = self.on_button_press) btn2 = Button(text= ''Hello Python'', color= [0,0,1,1], font_size= 20, size_hint= (.4, .25), pos_hint= {''center_x'':.5, ''center_y'':.2}) flo.add_widget(btn1) btn2.bind(on_press = self.on_button_press) flo.add_widget(btn2) return flo if __name__ == ''__main__'': ButtonApp().run()
Output
Run the above code and press the buttons −
On each press, the callback() method is invoked −
Hello World Button pressed! Hello Python Button pressed!
Binding Property
As mentioned earlier, we can bind a callback to a property of a widget. Every time the value of the property changes, the callback is invoked to notify the change.
btn1.bind(property=callback)
Let us define another method “on_textchanged()” in the App class, and bind it with the text property of btn2. The on_press event on btn1 changes the caption of btn2, and the change invokes the on_textchanged() method immediately.
Example
Change the code for ButtonApp class as below −
from kivy.app import App from kivy.uix.button import Button from kivy.config import Config from kivy.uix.floatlayout import FloatLayout # Configuration Config.set(''graphics'', ''width'', ''720'') Config.set(''graphics'', ''height'', ''400'') Config.set(''graphics'', ''resizable'', ''1'') class ButtonApp(App): def on_button_press(self, instance): print("{} Button pressed!".format(instance.text)) self.btn2.text="Hello Tutorialspoint" def on_textchanged(self, instance, value): print ("Text property changed to", instance.text) def build(self): flo = FloatLayout() self.btn1 = Button(text= ''Hello World'', background_color= [1,0,0,1], font_size= 20, underline= True, size_hint= (.4, .25), pos_hint= {''center_x'':.5, ''center_y'':.8}) self.btn1.bind(on_press = self.on_button_press) self.btn2 = Button(text= ''Hello Python'', color= [0,0,1,1], font_size= 20, size_hint= (.4, .25), pos_hint= {''center_x'':.5, ''center_y'':.2}) flo.add_widget(self.btn1) self.btn2.bind(text = self.on_textchanged) flo.add_widget(self.btn2) return flo if __name__ == ''__main__'': ButtonApp().run()
Output
Run the code and first press btn1. It changes the caption of btn2 and it in turn calls the “on_textchanged()” method.
Hello World Button pressed! Text property changed to Hello Tutorialspoint
Here”s the output window −
In general, property callbacks are called with two arguments (the object and the property”s new value) and “event callbacks” with one argument (the object).
Binding using Lambda Function
Another approach for binding is to use lambda (or anonymous) function. Their advantage is that you can avoid declaring new functions i.e. they offer a concise way to “redirect” callbacks.
Change the statement that binds the “on_press” event of btn1 to −
self.btn1.bind(on_press = lambda btn1: self.on_button_press(btn1))
Using Partial Function
In Python, a Partial function allows us to derive a function with x parameters to a function with fewer parameters and constant values set for the more limited function. It makes a function reusable. The partial() function is defined in functools module of Python”s standard library.
Example
We can bind an event to a partial method. In the example below, the Button objects bt1 and btn2 are passed. The function interchanges the text property of the two.
from kivy.app import App from kivy.uix.button import Button from kivy.config import Config from kivy.uix.floatlayout import FloatLayout from functools import partial # Configuration Config.set(''graphics'', ''width'', ''720'') Config.set(''graphics'', ''height'', ''300'') Config.set(''graphics'', ''resizable'', ''1'') class ButtonApp(App): def on_textchanged(self, instance, value): print ("Text property changed to", instance.text) def a_function(self, *args): args[0].text, args[1].text = args[1].text, args[0].text def build(self): flo = FloatLayout() self.btn1 = Button(text= ''Hello World'', background_color= [1,0,0,1], font_size= 20, underline= True, size_hint= (.4, .25), pos_hint= {''center_x'':.5, ''center_y'':.8}) self.btn2 = Button(text= ''Hello Python'', color= [0,0,1,1], font_size= 20, size_hint= (.4, .25), pos_hint= {''center_x'':.5, ''center_y'':.2}) flo.add_widget(self.btn1) self.btn1.bind(on_press = partial(self.a_function, self.btn1, self.btn2)) self.btn2.bind(text = self.on_textchanged) flo.add_widget(self.btn2) return flo if __name__ == ''__main__'': ButtonApp().run()
Output
Take a look at the following output window and observe how pressing the first button interchanges the text of the two buttons −
”;