【问题标题】:How to put an animation on a thread in kivy如何在kivy中的线程上放置动画
【发布时间】:2021-12-31 10:22:38
【问题描述】:

我正在为应用程序制作加载屏幕,但在同时运行动画和算法(需要很长时间才能运行)时遇到了一点问题。但是,当我运行该代码块时,当我尝试调用“self.ids.loading_anim”时,出现错误 AttributeError: 'super' object has no attribute 'getattr'。任何人都可以推荐一种更好的方法来在 kivy 中多线程动画吗?请记住,当我对其他算法进行多线程处理时,运行时间太长。

Python 代码:

def animate_image(self):
    anim = Animation()  
    anim.start(self.ids.loading_anim)

class LoadingWindow(Screen):
    def on_enter(self):
        t = Thread(target=animate_image, args=(self))
        t.deamon = True 
        t.start()

        for x in range(5):
            print(x)        # this is just a test algorithm which takes 5 seconds to run
            time.sleep(1)   # in the real file there is another algorithm which takes time to run

基维代码

<LoadingWindow>
    FloatLayout:
        Image:
            id: animation
            source: 'loading.gif'
            size_hint_x:0.6
            size_hint_y:0.6
            pos_hint: {'x':0.19, 'y':0.2}
            allow_stretch: True
            anim_delay: 0
            anim_reset: True
        Label:
            text: 'Searching the internet for recipes....'
            pos_hint: {'x':0, 'y':0.3}
            font_size: 28
        

【问题讨论】:

标签: python multithreading kivy


【解决方案1】:

首先,我认为函数animate_image()可以放在类里面?

你得到的错误是因为 self.ids 没有名为 loading_anim 的密钥,我认为通过引用 .kv 文件应该是 animation

另一方面,我认为您也可以线程化算法?

我还将类 MyApp 与 Inherit 添加到 kivy.app.App 并将 LoadingWindow 类放入 kivy ScreenManager。看看这是不是你想要的。

from threading import Thread
import time

import kivy
from kivy.clock import Clock
from kivy.app import App
from kivy.animation import Animation
from kivy.uix.screenmanager import Screen, ScreenManager

kivy.lang.Builder.load_string("""
#:kivy 2.0.0

<LoadingWindow>

    FloatLayout:
    
        Image:
            id: animation
            source: 'loading.gif'
            size_hint_x:0.6
            size_hint_y:0.6
            pos_hint: {'x':0.19, 'y':0.2}
            allow_stretch: True
            anim_delay: 0
            anim_reset: True
            
        Label:
            text: 'Searching the internet for recipes....'
            pos_hint: {'x':0, 'y':0.3}
            font_size: 28

""")


class LoadingWindow(Screen):
    
    def animate_image(self):  # can you put the animate_image() function to here ?
        anim = Animation()
        # anim.start(self.ids.loading_anim)  # I think it should be animation ref to the .kv file ?
        anim.start(self.ids.animation)
        
    
    def your_algorithm(self):
        
        for x in range(5):
            print(x)        # this is just a test algorithm which takes 5 seconds to run
            time.sleep(1)   # in the real file there is another algorithm which takes time to run
            
            
    def on_enter(self):
        t = Thread(target = self.animate_image)
        t.deamon = True
        t.start()
        
        # instead of threading the animation , I think you can also thread the algorithm ?
        algorithm = Thread(target = self.your_algorithm)
        algorithm.start()


class MyApp(App):
    screen_manager = ScreenManager()
    
    def build(self):
        # add screen to screen manager
        self.screen_manager.add_widget(LoadingWindow(name = "LoadingWindow"))
        
        return self.screen_manager


MyApp().run()

欢迎任何其他建议/建议/更好的方法/等:)

(英语不好请见谅)

【讨论】:

    【解决方案2】:

    on_pre_enteron_enter 我也有类似的问题

    据我所知,函数 on_pre_enteron_enter 在加载屏幕 ID 之前被调用,但我找到了一种可以使用的方法

    试试这个代码:

    from kivy.clock import Clock
    
    def animate_image(self):
        anim = Animation()  
        anim.start(self.ids.loading_anim)
    
    class LoadingWindow(Screen):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            Clock.schedule_once(self.init_completed)
        def init_completed(self, dt):
            t = Thread(target=animate_image, args=(self))
            t.deamon = True 
            t.start()
    
            for x in range(5):
                print(x)        # this is just a test algorithm which takes 5 seconds to run
                time.sleep(1)   # in the real file there is another algorithm which takes time to run
    

    正如我在Screen 中所说,on_pre_enteron_enter 在 ids 加载之前被调用,但是通过这种方式,ids 被加载然后你的函数 init_completed 被调用

    为我工作。

    【讨论】:

      猜你喜欢
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 2013-08-28
      • 2014-08-26
      • 2018-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多