Kivy - 按钮事件
按钮,与 Kivy 中的大多数 GUI 小部件一样,被编程为响应特定类型的事件。按钮处理以下事件类型 −
on_press − 按下按钮时触发。
on_release − 释放按钮时触发。
on_touch_down − 按钮上开始触摸事件时触发。
on_touch_up −当按钮上的触摸事件结束时触发。
Kivy 的 EventDispatcher 类提供了一个 bind() 方法,该方法负责将事件委托给某个回调函数进行处理。
EventDispatcher.bind(self, **kwargs)
Button(每个 Kivy 小部件也是如此)继承了此方法。因此,我们可以将 Button 对象绑定到任何回调事件处理程序函数。您还可以将属性绑定到回调。
绑定事件
下面给出了将按钮的 on_press 事件绑定到函数的典型方法 −
def callback(instance): print('The button is being pressed') btn1 = Button(text='Hello world') btn1.bind(on_press=callback)
示例
在下面的示例中,我们在 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()
输出
运行上述代码并按下按钮 −
每次按下按钮时,都会调用callback()方法−
Hello World Button pressed! Hello Python Button pressed!
绑定属性
如前所述,我们可以将回调绑定到小部件的属性。每次属性值发生变化时,都会调用回调来通知更改。
btn1.bind(property=callback)
让我们在App类中定义另一个方法"on_textchanged()",并将其与btn2的text属性绑定。 btn1 上的 on_press 事件会更改 btn2 的标题,并且此更改会立即调用 on_textchanged() 方法。
示例
将 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()
输出
运行代码并首先按下 btn1。它会更改 btn2 的标题,然后调用"on_textchanged()"方法。
Hello World 按钮已按下! 文本属性更改为 Hello Tutorialspoint
这是输出窗口 −
通常,属性回调使用两个参数(对象和属性的新值)调用,而"事件回调"使用一个参数(对象)。
使用 Lambda 函数进行绑定
另一种绑定方法是使用 lambda(或匿名)函数。它们的优点是您可以避免声明新函数,即它们提供了一种"重定向"回调的简洁方法。
将绑定 btn1 的"on_press"事件的语句更改为 −
self.btn1.bind(on_press = lambda btn1: self.on_button_press(btn1))
使用部分函数
在 Python 中,部分函数允许我们将具有 x 个参数的函数派生为具有更少参数的函数,并为更有限的函数设置常量值。它使函数可重复使用。partial() 函数在 Python 标准库的 functools 模块中定义。
示例
我们可以将事件绑定到部分方法。在下面的示例中,传递了按钮对象 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()
输出
查看以下输出窗口,观察按下第一个按钮如何交换两个按钮的文本 −