Lily H.
Lily H.

Reputation: 194

Kivy Widget not moving

When the program runs, the ScreenManager shows the Main screen on which I added the white little square(Ball).

The widget Ball should be moving around but I cannot figure out why it is still static. The update method is working but the position of the widget is not being updated. I tried to move things around and no effect.

If someone could help me to understand where I am wrong, would be great. Thx so much.

import kivy
kivy.require('1.10.1')
from kivy.app import App
from kivy.core.window  import Window
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.graphics import Rectangle
from kivy.uix.widget import Widget
from kivy.properties import ListProperty
from kivy.clock import Clock

# simple Screen on which the ball should move
class Main(Screen):
    def __init__(self, **kwargs):
        super(Main, self).__init__(**kwargs)
        self.add_widget(Ball())
        with self.canvas.before:
            Rectangle(source = 'BG1.png',
                      size = Window.size,
                      pos = self.pos)

# the Ball should be bouncing around
class Ball(Widget):
    velocity = ListProperty([10, 15])
    def __init__(self, **kwargs):
        super(Ball, self).__init__(**kwargs)
        Clock.schedule_interval (self.update, 1 / 60)

        with self.canvas:
            Rectangle (color=[0, 0, 0, 1],
                       size=(10, 10),
                       pos = self.pos)

    def update(self, *args):
        print('wtf')
        self.x += self.velocity[0]
        self.y += self.velocity[1]

        if self.x < 0 or (self.x + self.width) > Window.width:
            self.velocity[0] *= -1
        if self.y < 0 or (self.y + self.height) > Window.height:
            self.velocity[1] *= -1

Window.size = (400, 300)
sm = ScreenManager()
sm.add_widget(Main(name = 'main'))

class Bubble(App):
    def build(self):
        return sm

if __name__ == '__main__':
    Bubble().run()

Upvotes: 0

Views: 283

Answers (3)

Lily H.
Lily H.

Reputation: 194

Thank you Embryo and John, your answers led me to find the right answer. I found this code on this blog. Solved it all:Kivy blog

from kivy.uix.widget import Widget
from kivy.graphics import Rectangle, Color

class CornerRectangleWidget(Widget)
    def __init__(self, **kwargs):
        super(CornerRectangleWidget, self).__init__(**kwargs)

        with self.canvas:
            Color(1, 0, 0, 1)  # set the colour to red
            self.rect = Rectangle(pos=self.center,
                                  size=(self.width/2.,
                                        self.height/2.))

        self.bind(pos=self.update_rect,
                  size=self.update_rect)

    def update_rect(self, *args):
        self.rect.pos = self.pos
        self.rect.size = self.size

Upvotes: 2

John Anderson
John Anderson

Reputation: 38822

The problem is that when you set up Canvas instructions in python (rather than in kv), you don't get the automatic bindings that kv does for you. So the Rectangle that you define in the Ball.__init__() method gets its pos defined as the pos of the Ball at its __init__() moment (which is [0,0]), and it does not change automatically. You can fix that by doing the update yourself. First, in your Ball.__init__() change your with self.canvas block to:

    with self.canvas:
        Color(0,0,0,1)
        self.rect = Rectangle (size=(10, 10),
                   pos = self.pos)

One change is defining the Color, and the second is creating a reference to the Rectangle. Then in your update method add the line:

self.rect.pos = self.pos

This will move the rectangle with the Ball position.

Also, your update method has some problems because the size of the Ball is the same size as the Window. It is not the size you provide in the Rectangle.

Upvotes: 1

noEmbryo
noEmbryo

Reputation: 2231

Well, what is happening is this...

You are drawing the rectangle once, when you instantiate the Ball widget.
This is what you see in the bottom left corner.
After that you move the widget, but you don't draw it again.

If you print(self.pos) in the update function, you'll see it moving...

Upvotes: 0

Related Questions