Reputation: 2120
I have a Kivy carousel and each slide contains a float layout with an image and some labels on it. When I move to the next slide I want the image to animate. I am not using KV language for specific reasons, I am doing everything in python script.
I can get animation working so long as I don't try to position the widget I want to animate within the float layout. As soon as I position the widget it will not animate anymore.
Clearly positioning the widget locks it in place and it can't move anymore so can't be animated. How do I get the effect that I want?
Here is some working code that illustrates the problem.
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()
If you run this script it will animate the image. Changing the self.current_slide.children[k]
subscript will animate the label. But as soon as you uncomment the pos_hint
parameters the animation won't work anymore.
Upvotes: 0
Views: 587
Reputation: 38962
To animate pos_hint
, you must specify that property when you create the animation. For example:
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
Now you can use the pos_hint
to specify the starting position, as your commented out code does:
image.pos_hint = {'x': 0.25, 'y': 0.25}
hello.pos_hint = {'bottom': 1, 'left': 1}
Three things to note:
pos_hint
keys bottom
and left
are not valid. Legal keys are ‘x’, ‘right’, ‘center_x’, ‘y’, ‘top’ and ‘center_y’.center_x
hint, but center_x
is not in the initial pos_hint
, then it will have no effect.pos_hint
takes precedence over pos
, so animating pos
of a widget that is originally positioned using pos_hint
, will have no effect.Upvotes: 1