每次调用时如何重新启动 kivy 动画?

How can I restart kivy animation every time its called upon?

我正在制作一个简单的天气应用程序。用户输入一个位置并以纯文本形式获得结果。我制作了一个带有旋转动画的加载屏幕。当程序加载这些天气结果时,它会切换到加载屏幕并且动画旋转得很好。

我现在将动画设置为 20 秒。这允许我的加载屏幕的第一个实例显示足够的时间来产生结果,然后切换到结果屏幕(通常大约 5 秒)。看起来效果不错。

我的问题是:一旦动画完成 20 秒 运行(在后台),再次调用时它不会重新启动。该应用程序似乎只允许调用一次。要再次激活,应用必须完全关闭并重新启动。

理想情况下,我希望动画停止旋转并在加载屏幕退出后立即重置(因此一旦结果已交付)。用户可以多次获取天气,所以我需要在每次显示加载屏幕时重新开始。

我已经尝试了让它在后台不断旋转的不受欢迎的解决方案,这样当显示加载屏幕时,它就会旋转。

但是,即使那样我也很难让它重复...(anim.repeat = True 对我不起作用)

这是一个工作示例,它已被尽可能地剥离,但仍然与我的真实应用程序一样。

main.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
from kivy.animation import Animation
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):
    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"]
        anim = Animation(angle=-2000, duration=20)
        anim.repeat = True # this doesn't seem to work?
        anim.start(widget)

    def thread1(self): # this starts the actual "work" of the app by calling get_briefing() below
        p2 = Thread(target=lambda: self.get_briefing())
        p2.start()

    def get_briefing(self):
        time.sleep(5)# I have added a 5sec sleep to emulate work being done
        self.change_screen("results_1_screen") # screen change from loading screen to results screen after work complete
TestApp().run()

main.kv(仅用于屏幕管理)

#:import utils kivy.utils
#:include kv/homescreen.kv
#:include kv/results1screen.kv
#:include kv/loadscreen.kv
GridLayout:
    cols: 1
    FloatLayout:
        canvas:
            Rectangle:
                size: self.size
                pos: self.pos
        pos_hint: {"top": 1, "left": 1}
        size_hint: 1, 0
    ScreenManager:
        id: screen_manager
        HomeScreen:
            name: "home_screen"
            id: home_screen
        Results1Screen:
            name: "results_1_screen"
            id: results_1_screen
        LoadScreen:
            name: "load_screen"
            id: load_screen

homescreen.kv

<HomeScreen>:
    FloatLayout:
        canvas:
            Color:
                rgb: utils.get_color_from_hex("#000523")
            Rectangle:
                size: self.size
                pos: self.pos
    Button:
        text: "GO!"
        pos_hint:  {"top": .2, "center_x": .5}
        size_hint: .5, .08
        padding: 20, 20
        on_release:
            app.spin_widget()
            app.change_screen("load_screen") # widget spinning and going to load screen
            app.thread1() # start the app working in background

results1screen.kv(在实际应用中,这显示了所需的结果)

<Results1Screen>:
    FloatLayout:
        canvas:
            Color:
                rgb: utils.get_color_from_hex("#000523")
            Rectangle:
                size: self.size
                pos: self.pos
    Label:
        text: "RESULTS"
        pos_hint: {"top": .9, "center_x": .5}
        size_hint: 1, .1
    Button:
        text: "back"
        size_hint: .1, .1
        on_release:
            app.change_screen("home_screen")

loadscreen.kv

<LoadScreen>:
    FloatLayout:
        canvas:
            Color:
                rgb: utils.get_color_from_hex("#000523")
            Rectangle:
                size: self.size
                pos: self.pos
        Label:
            text: "loading"
        SpinningWidget:
            id: spinning_widget
            angle: 0
            size_hint: .1, .1
            pos_hint: {"center_x": .5, "center_y": .6}
<SpinningWidget@Image>
    angle: 0
    canvas.before:
        PushMatrix
        Rotate:
            angle: root.angle
            axis: 0, 0, 1
            origin: root.center
    canvas.after:
        PopMatrix

get_briefing 功能完成后,我尝试了几种退出或重置旋转小部件功能的方法,但无济于事。我已经尝试 anim.cancel()exit(self.spin_widget()) 之类的东西试图重置它,为下一次调用做好准备。

有人可以帮我解决这个问题吗,我似乎无法在 Kivy 文档或其他任何在线网站上找到答案。谢谢。

尝试在每个 Animation:

之前将 angle 重置为 0
def spin_widget(self):
    widget = self.root.ids["load_screen"].ids["spinning_widget"]
    widget.angle = 0
    anim = Animation(angle=-2000, duration=20)
    anim.repeat = True # this doesn't seem to work?
    anim.start(widget)

问题是在第一个 Animation 之后,angle 的值是 -2000,所以之后的任何 Animation 实际上都不会改变角度。 repeat.

同样的问题