Search code examples
pythonkivygifanimated-gif

Python / Kivy / Gif : How to remove gif after animation


I want to have a Gif as an opening animation that is deleted or moved away after the animation. However nothing seems to work, the image just stays there.

from kivy.uix.widget import Widget
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.button import Button
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.textinput import TextInput
from kivy.core.text import LabelBase
from kivy.uix.image import Image
from kivy.properties import StringProperty
from kivy.lang import Builder
from kivy.factory import Factory
from kivymd.app import App
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.extras.highlight import KivyLexer
from kivy.lang.parser import ParserException
from kivy.properties import ColorProperty
from kivymd.uix.label import MDLabel
from kivy.animation import Animation
from kivy.uix.screenmanager import ScreenManager, Screen

import time
import threading
import random

kv = ("""   
FloatLayout:
    canvas.before:
        Rectangle:
            pos: self.pos
            size: self.size
            source: 'test_back.png'

    Image:
        id: intro
        source: 'test_anim.gif'
        size_hint: None, None
        size: "500dp", "500dp"
        pos_hint: {'center_x':.5, 'center_y':.5}
        allow_stretch: False
        anim_delay: 0.05
        anim_loop: 1

""")

class testApp(App):
    def build(self):
        kivy_design = Builder.load_string(kv)
        self.app_root = kivy_design
        return kivy_design

    def on_start(self):
        frame_counter = 0
        frame_counter += 1
        if frame_counter == 30:
            self.app_root.ids.intro.pos_hint = {'center_x':-.5, 'center_y':-.5}

testApp().run()

I tried now for quite some time and also looked at other similar issues like this.

What am I missing? Thanks for reading


Solution

  • You can schedule the removal of the intro, and keep delaying that removal until the gif stops. Here is a modified version of your code that does that:

    from kivy.clock import Clock
    from kivy.lang import Builder
    from kivymd.app import App
    
    kv = ("""   
    FloatLayout:
        canvas.before:
            Rectangle:
                pos: self.pos
                size: self.size
                source: 'test_back.png'
    
        Image:
            id: intro
            source: 'test_anim.gif'
            size_hint: None, None
            size: "500dp", "500dp"
            pos_hint: {'center_x':.5, 'center_y':.5}
            allow_stretch: False
            anim_delay: 0.05
            anim_loop: 1
            on_texture: app.texture_updated()  # this lets us know every frame
    
    """)
    
    class testApp(App):
        def build(self):
            kivy_design = Builder.load_string(kv)
            self.app_root = kivy_design
            return kivy_design
    
        def on_start(self):
            # schedule removal of intro gif
            self.remove_it = Clock.schedule_once(self.remove_gif, self.root.ids.intro.anim_delay * 2)
    
        def texture_updated(self):
            # gif has been updated, so cancel removal
            self.remove_it.cancel()
    
            # reschedule removal
            self.remove_it = Clock.schedule_once(self.remove_gif, self.root.ids.intro.anim_delay * 2)
    
        def remove_gif(self, dt):
            # actually remove the intro gif
            self.root.remove_widget(self.root.ids.intro)
    
    
    
    testApp().run()