Kivy 简明教程

Kivy - Button Events

在 Kivy 中,大多数 GUI 小部件的按钮都会被编程为响应特定类型的事件。按钮处理以下事件类型 −

  1. on_press − 按钮按下时触发。

  2. on_release − 按钮松开时触发。

  3. on_touch_down − 触摸事件在按钮上开始时触发。

  4. 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()

Output

运行以上代码并按下按钮 −

kivy button events1

每次按下时,将会调用 callback() 方法 −

Hello World Button pressed!
Hello Python Button pressed!

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()

Output

运行代码,并先按 btn1 。它会更改 btn2 的说明,然后调用 "on_textchanged()" 方法。

Hello World Button pressed!
Text property changed to Hello Tutorialspoint

以下是输出窗口 −

kivy button events2

通常,属性回调会使用两个参数(对象和属性的新值)进行调用,而 "事件回调" 会使用一个参数(对象)。

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 对象 bt1btn2 。该函数交换了两个文本属性。

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

查看以下输出窗口并观察按下第一个按钮如何交换两个按钮的文本 −

button hello word