Kivy - 事件



Kivy 是一个 Python 库,可以帮助您构建跨平台的 GUI 应用程序。任何 GUI 应用程序都是事件驱动的,其中程序的流程不是顺序的(从上到下),而是由用户与界面上的控件交互来决定的。用户操作,例如单击按钮、“从列表中选择一个项目”或“从可用的单选按钮中选择一个选项”等,称为事件

基于 GUI 的程序会预料到其环境中可能发生的所有事件,并在某个事件发生时(以及如果发生)将其分派给相应的处理程序函数。

Kivy Events

当调用 Kivy 的 App 对象的 run() 方法时,应用程序会启动一个“事件监听”循环,并为每种类型的事件触发相应的回调函数。

全局事件调度器

Kivy 框架包含 EventDispatcher 类。它将事件对象分派到控件树,并且事件会通过控件层次结构传播。当处于可以处理事件位置的控件时,其关联的回调处理程序会被触发。控件、动画时钟类是事件调度器的示例。

Clock 是一个全局事件调度器,允许您在特定间隔安排和触发事件。它定义了诸如 'schedule_once()' 和 'schedule_interval()' 之类的方法来注册要在一定延迟后或定期调用的函数或方法。此机制对于处理定时事件、动画更新和应用程序中的其他重复任务很有用。

示例

在以下示例中,我们在控件树中放置了一个标签和两个按钮。标题为“开始”的按钮安排一个事件每秒定期发生一次。schedule_interval() 函数使用以下语法编写:

Clock.schedule_interval(callback, timeout)

另一方面,标题为“停止”的第二个按钮调用 unscheduled() 方法,该方法会删除已安排的事件。

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock
from kivy.config import Config

# Configuration
Config.set('graphics', 'width', '720')
Config.set('graphics', 'height', '400')
Config.set('graphics', 'resizable', '1')

class DemoApp(App):
   def build(self):
      lo = BoxLayout(orientation='vertical')
      self.l1 = Label(text="0", font_size=100)
      self.b1 = Button(text="start", font_size=100, color=(0, 0, 1, 1))
      
      self.b1.bind(on_press=self.onstart)
      self.b2 = Button(text="Stop", font_size=100, color=(1, 0, 0, 1))
      self.b2.bind(on_press=self.onstop)
      lo.add_widget(self.l1)
      lo.add_widget(self.b1)
      lo.add_widget(self.b2)
      return lo

   def onstart(self, event):
      print("started")
      Clock.schedule_interval(self.update_label, 1)

   def onstop(self, event):
      Clock.unschedule(self.update_label)

   def update_label(self, event):
      self.l1.text = str(int(self.l1.text) + 1)

if __name__ == '__main__':
   DemoApp().run()

输出

运行上述程序。标签最初显示“0”。单击“开始”按钮。标签开始每秒在其上递增数字。按“停止”按钮取消安排事件。

Kivy Events

控件事件

大多数 Kivy 控件都具有内置的事件处理功能。事实上,每个控件都设计为处理特定类型的事件。例如,Button 控件处理单击它引起的事件。您可以为控件上发生的特定事件(例如按钮单击、触摸事件或键盘事件)注册事件处理程序。

通常,事件处理程序在控件的类或 App 类中定义为方法。它们通常以“on_”为前缀,后跟事件的名称。例如,按钮按下事件的“on_press”。

当事件发生时,Kivy 会自动调用相应的事件处理程序方法,并将有关事件的相关信息作为参数传递。在事件处理程序内部,您可以定义要执行的所需行为或操作。

与控件关联的事件

下面列出了与一些最常用控件关联的事件:

按钮

  • on_press - 按下按钮时触发。

  • on_release - 释放按钮时触发。

  • on_touch_down - 按钮上开始触摸事件时触发。

  • on_touch_up - 按钮上结束触摸事件时触发。

TextInput

  • on_text_validate - 用户完成文本输入编辑(按 Enter 或 Return)时触发。

  • on_focus - 文本输入获得或失去焦点时触发。

  • on_text - 输入字段中的文本发生更改时触发。

复选框

  • on_active - 复选框选中或取消选中时触发。

滑块

  • on_value - 滑块的值发生更改时触发。

  • on_touch_down - 滑块上开始触摸事件时触发。

  • on_touch_up - 滑块上结束触摸事件时触发。

切换按钮

  • on_state - 切换按钮的状态发生更改(打开或关闭)时触发。

  • on_press - 按下切换按钮时触发。

ListView

  • on_select - 列表视图中选择一个项目时触发。

FileChooser

  • on_selection - 在文件选择器中选择文件或目录时触发。

开关

  • on_active - 开关打开或关闭时触发。

视频

  • on_load - 视频加载完成时触发。

  • on_play - 视频开始播放时触发。

  • on_pause - 视频暂停时触发。

  • on_stop - 视频停止播放时触发。

微调器

  • on_text - 从微调器中选择一个项目时触发。

ActionButton

  • on_press - 按下操作按钮时触发。

示例 - Kivy 中的事件处理

在解释 Kivy 框架中的每个控件时,将讨论这些事件。但是,在本节中,这里提供了两个事件处理示例。

示例 1

第一个示例显示 Button 控件的“on_press”事件。在下面的代码中,我们有一个 Label 和一个 Button 控件,排列在 BoxLayout 中。要处理 on_press 事件,我们将按钮绑定到 DemoApp 类中定义的 onstart() 方法

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.config import Config

# Configuration
Config.set('graphics', 'width', '720')
Config.set('graphics', 'height', '400')
Config.set('graphics', 'resizable', '1')

class DemoApp(App):
   def build(self):
      lo = BoxLayout(orientation='vertical')
      self.l1 = Label(text="0", font_size=100)
      self.b1 = Button(text = "start", font_size = 100, color=(1,0,0,1))
      self.b1.bind(on_press=self.onstart)
      lo.add_widget(self.l1)
      lo.add_widget(self.b1)
      return lo

   def onstart(self, event):
      print ("started")
      self.l1.text = str(int(self.l1.text)+1)

if __name__ == '__main__':
   DemoApp().run()

输出

将上述代码另存为“demo.py”,然后从命令行或 Python IDE 运行它。程序以标签显示 0 作为其标题开始。每次单击按钮时,标题都会加 1。

Kivy Events Start

示例 2

在此示例中,我们有一个 TextInput 控件和一个 Label。TextInput 绑定到 onkey() 方法。用户输入的每个按键都反映在 Label 上。

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.boxlayout import BoxLayout

from kivy.clock import Clock
from kivy.core.window import Window

Window.size = (720,400)

class DemoApp(App):
   def build(self):
      lo = BoxLayout(orientation='vertical')
      self.t1 = TextInput(multiline=False)
      self.l1 = Label(font_size=50)
      self.t1.bind(text=self.onkey)

      lo.add_widget(self.t1)
      lo.add_widget(self.l1)
      return lo
      
   def onkey(self, event, value):
      print ("press")
      self.l1.text = value

if __name__ == '__main__':
   DemoApp().run()

输出

运行程序并在文本框中输入一些文本。当您键入时,Label 标题会更新。

Kivy Events Msg

还可以定义自定义事件和事件处理程序来处理特定于应用程序的事件。为此,您需要对 'EventDispatcher' 类进行子类化并定义所需的属性和方法。

可以使用与控件事件类似的 'trigger()' 和 'on_event_name' 模式来分派和处理自定义事件。

广告