如何在Kivy-Python中停止Widget的循环缩放动画?
Kivy循环缩放动画无法停止的解决方案
你的代码核心问题是**animate_zoom方法中创建的Animation对象是局部变量,未赋值给类实例的self.anim_zoom_in和self.anim_zoom_out属性**,导致stop_animation方法里判断的self.anim_zoom_in始终为None,根本没执行取消动画的逻辑。
修复步骤及优化后的代码如下:
from kivy.uix.widget import Widget from kivy.animation import Animation from kivy.metrics import dp class AnimationController: def __init__(self): self.anim_zoom_in = None self.anim_zoom_out = None # 保存回调引用,方便后续精准解绑 self.zoom_in_complete_cb = None self.zoom_out_complete_cb = None def animate_zoom(self, target_widget): # 将动画对象赋值给实例属性 self.anim_zoom_in = Animation(width=dp(60), height=dp(80), duration=1) self.anim_zoom_out = Animation(width=dp(80), height=dp(100), duration=1) # 定义命名回调函数,避免lambda无法精准解绑的问题 def on_zoom_in_done(*args): self.anim_zoom_out.start(target_widget) def on_zoom_out_done(*args): self.anim_zoom_in.start(target_widget) self.zoom_in_complete_cb = on_zoom_in_done self.zoom_out_complete_cb = on_zoom_out_done # 绑定完成回调 self.anim_zoom_in.bind(on_complete=self.zoom_in_complete_cb) self.anim_zoom_out.bind(on_complete=self.zoom_out_complete_cb) # 启动初始动画 self.anim_zoom_in.start(target_widget) def stop_animation(self, target_widget): # 先解绑回调,切断循环触发逻辑 if self.anim_zoom_in and self.zoom_in_complete_cb: self.anim_zoom_in.unbind(on_complete=self.zoom_in_complete_cb) self.anim_zoom_in.cancel(target_widget) if self.anim_zoom_out and self.zoom_out_complete_cb: self.anim_zoom_out.unbind(on_complete=self.zoom_out_complete_cb) self.anim_zoom_out.cancel(target_widget) # 可选:停止后重置控件到目标尺寸,避免停留在动画中间状态 target_widget.width = dp(80) target_widget.height = dp(100)
额外说明:
- 用命名函数代替lambda绑定回调,是因为lambda是匿名对象,后续unbind时无法精准匹配,导致解绑失效
- 停止动画后建议重置控件尺寸,避免控件停留在动画过程中的过渡状态
- 修正了原类名的拼写错误(
Animination改为AnimationController)
内容的提问来源于stack exchange,提问作者Rd6 Rd
相关产品推荐
相关产品推荐

