Kivy 简明教程
Kivy - Button Events
在 Kivy 中,大多数 GUI 小部件的按钮都会被编程为响应特定类型的事件。按钮处理以下事件类型 −
-
on_press − 按钮按下时触发。
-
on_release − 按钮松开时触发。
-
on_touch_down − 触摸事件在按钮上开始时触发。
-
on_touch_up − 触摸事件在按钮上结束时触发。
Kivy 的 EventDispatcher 类提供了一个 bind() 方法,此方法负责将事件委托给某个回调函数以进行处理。
EventDispatcher.bind(self, **kwargs)
Button(就像每个 Kivy 小组件一样)继承此方法。因此,我们可以将 Button 对象绑定到任何回调事件处理程序函数。您还可以将属性绑定到回调。
Binding Event
下面给出了一个典型的绑定 on_press 事件到按钮的方法 −
def callback(instance):
print('The button is being pressed')
btn1 = Button(text='Hello world')
btn1.bind(on_press=callback)
Example
在以下示例中,我们在 FloatLayout 中放置了两个按钮。每个按钮的 "on_press" 事件都绑定到 callback() 方法。
触发 "on_press" 事件的按钮的引用会传递给 callback() 方法,这样我们就可以识别按下的按钮的说明。
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()
Binding Property
如前所述,我们可以将回调绑定到小组件的属性。每当属性的值发生更改时,都会调用回调以通知更改。
btn1.bind(property=callback)
让我们在 App 类中定义另一个方法 "on_textchanged()",并将其与 btn2 的文本属性进行绑定。btn1 上的 on_press 事件会更改 btn2 的说明,而更改会立即调用 on_textchanged() 方法。
Example
将 ButtonApp 类的代码更改为如下 −
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()
Binding using Lambda Function
另一种绑定方式是使用 lambda(或匿名)函数。其优点是您无需声明新函数,即它们提供了一种简洁的方式来 "重定向" 回调。
将 btn1 的 "on_press" 事件绑定的语句更改为 −
self.btn1.bind(on_press = lambda btn1: self.on_button_press(btn1))
Using Partial Function
在 Python 中,Partial 函数允许我们将一个具有 x 个参数的函数转换为具有较少参数的函数,并为限制性更强的函数设置常数值。它让函数可以重复使用。 partial() 函数在 Python 标准库的 functools 模块中定义。
Example
我们可以在部分方法上绑定一个事件。在以下示例中,传递了 Button 对象 bt1 和 btn2 。该函数交换了两个文本属性。
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()