kivy官方乒乓教程:'NoneType'对象没有属性'center'

时间:2014-02-11 21:59:35

标签: python kivy

我正试图用this tutorial来学习Kivy。我已经将“这里是这一步的整个代码:”之后的代码复制粘贴到main.py和main.kv中,如上所述。在试图跑步时,我得到了:

Traceback (most recent call last):
  File "main.py", line 47, in <module>
   PongApp().run()
  File "/home/kivy/code/kivy/kivy/app.py", line 527, in run
   root = self.build()
  File "main.py", line 41, in build
   game.serve_ball()
  File "main.py", line 23, in serve_ball
   self.ball.center = self.center
AttributeError: 'NoneType' object has no attribute 'center'

我做错了什么?

main.kv:

#:kivy 1.0.9

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

<PongGame>:
    ball: pong_ball

    canvas:
        Rectangle:
            pos: self.center_x-5, 0
            size: 10, self.height

    Label:
        font_size: 70  
        center_x: root.width / 4
        top: root.top - 50
        text: "0"

    Label:
        font_size: 70  
        center_x: root.width * 3 / 4
        top: root.top - 50
        text: "0"

    PongBall:
        id: pong_ball
        center: self.parent.center

main.py:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty,\
    ObjectProperty
from kivy.vector import Vector
from kivy.clock import Clock
from random import randint


class PongBall(Widget):
    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)
    velocity = ReferenceListProperty(velocity_x, velocity_y)

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


class PongGame(Widget):
    ball = ObjectProperty(None)

    def serve_ball(self):
        self.ball.center = self.center
        self.ball.velocity = Vector(4, 0).rotate(randint(0, 360))

    def update(self, dt):
        self.ball.move()

        #bounce off top and bottom
        if (self.ball.y < 0) or (self.ball.top > self.height):
            self.ball.velocity_y *= -1

        #bounce off left and right
        if (self.ball.x < 0) or (self.ball.right > self.width):
            self.ball.velocity_x *= -1


class PongApp(App):
    def build(self):
        game = PongGame()
        game.serve_ball()
        Clock.schedule_interval(game.update, 1.0 / 60.0)
        return game


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

3 个答案:

答案 0 :(得分:5)

您的KV文件名称错误。它应该是“pong.kv”。如果KV文件的名称与您的应用程序名称(减去应用程序)匹配,那么它将自动使用。

您将您的KV文件命名为“main.kv”,该文件与您的应用名称“PongApp”不匹配,因此魔法没有发生。您可以使用Builder.load_file()手动加载KV文件。如果您回头看教程,可以看到它要求您将KV文件命名为“pong.kv”。

答案 1 :(得分:1)

我添加了

from kivy.lang import Builder

Builder.load_file('main.kv')

到我的main.py,它完美无缺。为什么“main.kv”没有被自动检测到,对我来说仍然是一个谜。

答案 2 :(得分:0)

self.ball正在初始化:

ball = ObjectProperty(None)

这使它的默认值为None。因此,当您尝试访问self.ball.center时,它会失败。

本教程包含您可能错过的步骤:

  

不要忘记将它挂钩到kv文件中,方法是给子窗口小部件一个id并将PongGame的球ObjectProperty设置为该id