如何解决Kivy加载页动画仅运行一次,每次调用时需重启动画的问题
问题根因
你遇到的两个核心问题本质都和动画状态管理有关:
- 第二次触发动画无效果:首次动画运行结束后,
spinning_widget的angle属性已经被修改为目标值-2000,你再次创建Animation(angle=-2000)时,控件当前属性和动画目标值完全一致,Kivy不会触发任何动画效果 anim.repeat = True看似无效:动画实例anim是spin_widget方法内的局部变量,方法运行结束后实例就会被回收,自然无法维持循环效果;同时你没有存储动画实例,也无法在后续主动停止动画
另外你在子线程直接调用UI操作(切换页面)也存在潜在崩溃风险,Kivy所有UI相关操作必须在主线程执行。
修复方案
只需修改main.py的对应逻辑即可,修改后的完整代码如下:
from kivy.app import App from kivy.lang import Builder from kivy.uix.screenmanager import Screen from kivy.animation import Animation from kivy.clock import Clock import time from threading import Thread class HomeScreen(Screen): pass class Results1Screen(Screen): pass class LoadScreen(Screen): pass GUI = Builder.load_file("main.kv") class TestApp(App): # 存储加载动画实例的属性 load_anim = None def build(self): return GUI def change_screen(self, screen_name): screen_manager = self.root.ids['screen_manager'] screen_manager.current = screen_name def spin_widget(self): widget = self.root.ids["load_screen"].ids["spinning_widget"] # 停止之前还在运行的动画,避免冲突 if self.load_anim: self.load_anim.cancel(widget) # 重置旋转角度为初始值,保证每次动画都从0度开始转 widget.angle = 0 # 这里角度改成-7200是20圈,20秒转完每秒一圈,效果更顺滑,你也可以保留原来的-2000 self.load_anim = Animation(angle=-7200, duration=20) self.load_anim.repeat = True self.load_anim.start(widget) def thread1(self): p2 = Thread(target=lambda: self.get_briefing()) p2.start() def get_briefing(self): time.sleep(5) # UI操作通过Clock调度到主线程执行,避免线程安全问题 Clock.schedule_once(self.end_loading, 0) def end_loading(self, dt): # 跳转页面前先停止动画,释放资源 widget = self.root.ids["load_screen"].ids["spinning_widget"] if self.load_anim: self.load_anim.cancel(widget) self.change_screen("results_1_screen") TestApp().run()
效果验证
修改后:
- 每次点击GO按钮,加载动画都会从0度开始正常旋转
- 动画循环效果正常,即使加载时间超过20秒也会一直旋转
- 跳转结果页后动画自动停止,不会后台占用资源
- 多次重复查询操作都能正常触发加载动画
内容的提问来源于stack exchange,提问作者PW1990
相关产品推荐
相关产品推荐

