Search code examples
pythonkivykivy-language

Unwanted duplicate kivy widget


I only want one ball widget displayed bouncing around on the screen. However two ball widget's are displayed, one moving and the other stationary positioned in the center of the screen. This is my python code:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty, NumericProperty, ReferenceListProperty
from kivy.lang.builder import Builder
from kivy.vector import Vector
from kivy.clock import Clock


refresh_rate = 1/60

Builder.load_file("./balls.kv")


class Balls(Widget):

    vx = NumericProperty(0)
    vy = NumericProperty(0)

    velocity = ReferenceListProperty(vx,vy)

    def move(self):
        self.pos = Vector(self.velocity) + self.pos


class BallsLogic(Widget):

    ball = ObjectProperty(None)

    def start(self):
        self.ball.velocity = 10, -3

    def update(self, dt):

        self.ball.move()

        if self.ball.y < self.y or self.ball.top > self.top:
            self.ball.vy *= -1

        if self.ball.x < self.x or self.ball.right > self.right:
            self.ball.vx *= -1


class BallsApp(App):

    def build(self):
        bl = BallsLogic()
        bl.start()
        Clock.schedule_interval(bl.update, refresh_rate)
        return bl


if __name__ == "__main__":
    BallsApp().run()

With the accompanying kv file:

#kivy 1.0.9

<Balls>
    size:50,50
    canvas:
        Ellipse:
            size: self.size
            pos: self.pos

<BallsLogic>
    ball: ball
    Balls:
        center: self.parent.center
        id: ball
        

I've tried re-writing the program to see where I may have gone wrong. I notice the issue when I implement the move method. One ball widget stay's in place, and the other zooms across the screen. I only want one ball widget bouncing around, and I can't figure out where the stationary one is coming from or why it isn't effected by the update or move methods.


Solution

  • Kivy will automatically load a properly named kv file, see the documentation. In your case, a kv file with the name balls.kv will automatically be loaded. Also, the code:

    Builder.load_file("./balls.kv")
    

    loads the same file. This results in the balls.kv file being loaded twice, and two Balls widgets being added to the BallsLogic widget. The fix is to simply remove the above line of code so that the balls.kv file only gets loaded once.