【问题标题】:Animate images on slides in a Kivy carouselKivy 轮播中幻灯片上的动画图像
【发布时间】:2020-10-23 11:14:49
【问题描述】:

我有一个 Kivy 轮播,每张幻灯片都包含一个浮动布局,上面有一张图片和一些标签。当我移至下一张幻灯片时,我希望图像具有动画效果。由于特定原因,我没有使用 KV 语言,我在 python 脚本中做所有事情。

只要我不尝试在浮动布局中放置我想要制作动画的小部件,我就可以让动画正常工作。只要我定位小部件,它就不会再动画了。

明确定位小部件会将其锁定到位,并且无法再移动,因此无法设置动画。如何获得我想要的效果?

这里有一些说明问题的工作代码。

import kivy     
from kivy.app import App  
from kivy.uix.carousel import Carousel 
from kivy.uix.image import AsyncImage  
from kivy.animation import Animation
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout

def animate():
    animation = Animation(pos=(20, 0), t='out_bounce')
    animation += Animation(pos=(-40, 0), t='out_bounce')
    animation += Animation(pos=(0, 0), t='out_bounce')
    return animation

class MyCarousel(Carousel):
    # This class is a carousel that runs script
    # when a slide gets focus (except first load).
    def on_index(self, *args):
        print('the slide is', self.index)
        # 1 is image, 0 is label
        animate().start(self.current_slide.children[1])
        Carousel.on_index(self, *args)

class CarouselApp(App): 
    def build(self): 
        # Set carousel widget as root 
        root = MyCarousel()  

        # Adding slides 
        for i in range(3): 
            flo = FloatLayout() # to test nesting animation
            src = "https://via.placeholder.com/480x270.png&text=slide-%d" %i             
            image = AsyncImage(source = src, allow_stretch = True) 
            hello = Label(text='Hello', font_size=50)

            # THESE KILL ANIMATION -----------------
            # image.pos_hint = {'x': 0.25, 'y': 0.25}
            # hello.pos_hint = {'bottom': 1, 'left': 1}
            # --------------------------------------

            image.size_hint = (0.5, 0.5)
            hello.size_hint = (0.25, 0.25)
            flo.add_widget(image)
            flo.add_widget(hello)
            root.add_widget(flo) 

        return root 
  
# run the App 
if __name__ == '__main__': 
    #breakpoint()
    app = CarouselApp()
    app.run() 

如果您运行此脚本,它将为图像设置动画。更改 self.current_slide.children[k] 下标将为标签设置动画。但是,一旦您取消注释 pos_hint 参数,动画将不再起作用。

【问题讨论】:

  • pos_hint 值优先于 pos 值。所以动画pospos_hint 设置为任何东西都行不通。您可以使用pos 而不是pos_hint 定位您的小部件,然后动画将起作用。
  • 或者您可以为pos_hint 属性设置动画。
  • 谢谢约翰,我将如何为 pos_hint 设置动画,这超出了我目前的知识范围,我们将不胜感激。我尝试了animate().start(self.current_slide.children[1].pos_hint) ,但没想到它会起作用,但它没有。
  • 按照约翰的建议,使用pos 代替pos_hint 动画作品。基本上,您只需将小部件的位置与其容器挂钩,在我的情况下是浮动布局。所以代码是image.pos = flo.centerhello.pos = flo.pos。这对我的情况非常具体,所以我希望有一个更通用的解决方案。

标签: python kivy


【解决方案1】:

要为pos_hint 设置动画,您必须在创建动画时指定该属性。例如:

def animate():
    animation = Animation(pos_hint={'x':.5, 'y':0}, t='out_bounce')
    animation += Animation(pos_hint={'x':-.2, 'y':0}, t='out_bounce')
    animation += Animation(pos_hint={'x':0, 'y':0}, t='out_bounce')
    return animation

现在您可以使用pos_hint 指定起始位置,就像您注释掉的代码所做的那样:

        image.pos_hint = {'x': 0.25, 'y': 0.25}
        hello.pos_hint = {'bottom': 1, 'left': 1}

注意三点:

  1. pos_hintbottomleft 无效。合法键是“x”、“right”、“center_x”、“y”、“top”和“center_y”。
  2. 您必须为最初用于定位小部件的键设置动画。如果您为center_x 提示设置动画,但center_x 不在初始pos_hint 中,则它将不起作用。
  3. pos_hint 优先于 pos,因此为最初使用 pos_hint 定位的小部件设置动画 pos 将无效。

【讨论】:

    猜你喜欢
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 2021-04-24
    • 1970-01-01
    • 2017-12-26
    相关资源
    最近更新 更多