当前位置: 首页 > news >正文

Kivy如何自定义事件

我们知道,在Kivy中,一个控件自带一些事件,这些事件会在控件上发生某些操作时被触发。例如,在Kivy教程 Kivy - 事件 - 技术教程 中,Button控件拥有on_press事件,在按钮被按下时会被触发。但这就引出了一个问题:除了控件中自带的一些事件,我们有没有可能自定义一些事件,在我们规定的条件下被触发呢?

答案是肯定的。Kivy里有一个库叫做kivy.event.EventDispatcher。自定义事件的方法都在这个库里,通过继承,把它并入已有的控件即可。

一、EventDispatcher使用说明

首先,把EventDispatcher这个库引入程序。

from kivy.event import EventDispatcher

然后,把定义事件的代码分为两部分。一部分在控件的类里,另一部分在程序的类里。

(一)控件类

我想给BoxLayout这类控件添加一些事件。这样的话,我需要创建一个新的类,基于BoxLayout但功能比标准的BoxLayout多一些自定义事件。所以,这个新的类要有两个“父类”,一个是BoxLayout本身,给予它作为一个BoxLayout的基本性质;另一个是EventDispatcher,给予它定义事件的方法,如register_event_type

class specialBox(BoxLayout, EventDispatcher): def __init__(self, *args, **kwargs): self.register_event_type('on_moving') # Event type must be registered at __init__ self.register_event_type('on_down') self.register_event_type('on_up') return super().__init__(*args, **kwargs) # Remember, super() function must be written

这个specialBox是一个特殊的类。它继承了BoxLayout,所以BoxLayout的所有功能(无论是内部还是外部的属性与方法,包括对外接口),specialBox对象都能正常用。但与此同时,在__init__函数中,这个类在原有的基础上,由于继承了EventDispatcher,所以要通过EventDispatcher给予的register_event_type方法,定义三个新事件:on_moving,on_down,on_up

注意:子类在重载函数,包括__init__函数,也包括其它函数时,在加入了额外的程序段的同时,务必不要遗漏原有的功能哦!否则会本末倒置,新的类该有的基本功能会失去,程序会异常。所以,最后一句return super().__init__(*args, **kwargs)不要忘记!

那么,事件在什么情况下触发,这个怎么定义呢?一般,事件在运行某个函数时触发。在这个例子中,我希望on_down事件在 specialBox 的on_touch_down函数中触发。你知道吗?对于一个BoxLayout控件,它自带一个功能,就是当被点击时,on_touch_down就会自动运行,而touch参数值就是点击的位置。请参见 Kivy - 输入 - 技术教程 (注意这个教程里的例子有一个致命的问题:遗漏了super().on_touch_down(touch)再次提醒:重载函数后原功能不要弄丢!)或者如果想看详细的说明,可以看这里:kivy 的on_touch_move和on_touch_down_触控手势是触摸屏输入的一种较常见的方式,kivy库提供了触控手势的识别,有了它,就-CSDN博客

def on_touch_down(self, touch): print("Down:",touch) self.dispatch('on_down') # So this event "on_down" will be triggered when on_touch_down is run return super().on_touch_down(touch)

言归正传,重载的函数on_touch_down里,有一句self.dispatch('on_down')。这句话,就是产生on_down事件的语句。

另外,对于定义的事件,必须在该类以内,定义一个对应的函数。这个函数可以是空的,但必须要有,否则报错。

def on_moving(self, *args): # Must define here first, otherwise error will happen pass def on_down(self, *args): pass def on_up(self,*args): pass

至此,事件的定义已经完成。刚才的代码都是在定义这个新的衍生类specialBox

(二)程序类

接下来的程序就是在App里了。要在程序里,把事件和函数绑定。

记得一个控件的自带事件是如何绑定函数的吗?比如按钮绑定自带的on_press事件的方法是

self.b1.bind(on_press=self.onstart)

那么绑定自定义事件的方法也一样。

class MotionApp(App): def build(self): self.box = specialBox(orientation='vertical') self.box.bind(on_down = self.ondown) # event on_down is binded to function self.ondown self.box.bind(on_moving = self.onmove) self.box.bind(on_up = self.onup)

事件名 = 函数。一样的配方。

二、示例

这个例子中,当界面被点击时,移动鼠标时,鼠标放开时,一些事件,包括自定义的事件,会被触发。触发的结果,可以在控制台里看见。

(一)代码

# -*- coding: utf-8 -*- """ Created on Thu May 21 17:06:15 2026 @author: iven.dong """ from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.event import EventDispatcher from kivy.uix.label import Label class specialBox(BoxLayout, EventDispatcher): def __init__(self, *args, **kwargs): self.register_event_type('on_moving') # Event type must be registered at __init__ self.register_event_type('on_down') self.register_event_type('on_up') return super().__init__(*args, **kwargs) # Remember, super() function must be written def on_touch_down(self, touch): print("Down:",touch) self.dispatch('on_down') # So this event "on_down" will be triggered when on_touch_down is run return super().on_touch_down(touch) def on_touch_move(self, touch): print("Move:","pos:",touch.pos, "spos", touch.spos) self.dispatch('on_moving') return super().on_touch_move(touch) def on_touch_up(self, touch): print("UP!",touch) self.dispatch('on_up') return super().on_touch_up(touch) def on_moving(self, *args): # Must define here first, otherwise error will happen pass def on_down(self, *args): pass def on_up(self,*args): pass class MotionApp(App): def build(self): self.box = specialBox(orientation='vertical') self.label = Label(text="Hello") self.box.add_widget(self.label) self.box.bind(on_down = self.ondown) # event on_down is binded to function self.ondown self.box.bind(on_moving = self.onmove) self.box.bind(on_up = self.onup) return self.box def ondown(self, event): print("on_down event is triggered in MotionApp") def onup(self, event): print("on_up event is triggered in MotionApp") def onmove(self, event): print("on_move event is triggered in MotionApp") if __name__ == '__main__': MotionApp().run()

在类 specialBox 中,事件on_downon_upon_move都是在初始化时定义的(请看self.register_event_type方法)。在点下鼠标,松开鼠标,移动鼠标时,事件会被触发(请看on_touch_down等函数里的self.dispatch方法)。在类 MotionApp 中,build里的self.box.bind就对这三个事件和函数做了绑定。控制台上的 “on_down event is triggered in MotionApp” 等语句,就是事件触发时运行的绑定函数的结果。

(二)运行效果

框出来的输出,就是自定义事件绑定的函数的运行结果。

三、总结

Kivy控件可以自定义事件,且将自定义的事件和外部函数绑定。自定义函数的方法由包EventDispatcher 提供。

http://www.gsyq.cn/news/1441293.html

相关文章:

  • 大语言模型(LLM)技术本质剖析:从Transformer到RAG的实践指南
  • 2026年铸铁井盖厂家推荐:山东隆工金属制品加工有限公司全品类供应 - 品牌推荐官
  • 做题记录(Jun.)
  • 避坑指南|萍乡本地黄金回收哪家靠谱?福满多黄金回收上门服务全解析 - 余生黄金回收
  • 基于晶体与分频器实现高精度50Hz时钟信号的硬件方案
  • 新余本地黄金回收痛点全拆解:上门回收就选福满多黄金回收,五家门店任你挑 - 余生黄金回收
  • League Akari:英雄联盟自动化工具完全指南 - 技术架构与实战应用深度解析
  • 告别激活烦恼:3分钟掌握Windows和Office智能激活方案
  • PCL2启动器内存管理终极指南:如何让Minecraft在低配电脑上流畅运行
  • 杭州沙发翻新,旧沙发翻新换皮,2026本地靠谱师傅推荐 - 天堂海洋
  • 2026乌鲁木齐家装全案与工装工程:本地口碑服务商实测盘点,附真实报价参考 - 优质企业观察收录
  • 五分钟搭建私有搜索引擎:SearXNG Docker 完整指南
  • 从‘锁不住’到‘锁得稳’:深入理解三相并网变流器中锁相环(PLL)的线性化建模与影响
  • 2026年6月东莞黄金回收指南:5家正规门店真实成交价一览 - 合扬奢侈品交易中心
  • 什么随身 wifi 好用又便宜?2026 真实测评,这几款值得入手 - 速递信息
  • 3步掌握AMD Ryzen调试:免费开源工具让你的处理器性能飙升50%
  • 2026水质测定仪选购指南:厂家推荐+避坑技巧,新手一看就懂 - 品牌优选官
  • SetDPI:Windows多显示器DPI精准控制的全新方案
  • QMCDecode终极指南:macOS上轻松解锁QQ音乐加密格式
  • 抖音批量下载神器:如何快速高效采集无水印视频内容
  • 抖音批量下载神器:5分钟掌握高效内容采集终极指南
  • 不要只懂 CAS:手把手带你手写面向 AI 推理的无锁 MPMC 队列
  • 小视频投票评选活动如何制作?微信投票工具教会你 - 微信投票小程序
  • 别再死磕验证方案文档了!一个资深验证工程师的UVM实战测试分解心法
  • 5分钟搭建你的专属暗黑破坏神2存档编辑器:可视化修改,解放游戏时间
  • 2026 杭州本地代理记账机构盘点 口碑服务商推荐 - 玖叁鹿
  • 【字节跳动】安全防护机制:实现熔丝保护、密钥轮换、硬件黑名单等安全措施,如权重补丁需通过34轮哈希校验(5178)资源管理:会话池支持2048个并发(SESS_POOL_MAX)显存资源闲置释放
  • 【限时解密】Veo 2隐藏API接口曝光:绕过WebUI直调4K生成管线,实测吞吐量提升4.8倍(仅剩最后17个内测密钥)
  • Gemini生物识别集成:如何在72小时内完成金融级FIDO2兼容改造?附可审计代码模板
  • 2026年6月深圳黄金回收行情测评,五大渠道横向对比! - 奢侈品回收测评