Skip to main content
 首页 » 编程设计

python之kivy官方乒乓教程: 'NoneType' object has no attribute 'center'

2025年05月04日15三少

我正在尝试通过 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' 

我做错了什么?

主.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 

主要.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() 

请您参考如下方法:

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

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