Kivy AttributeError: 'super' object has no attribute '__getattr__' error
Kivy AttributeError: 'super' object has no attribute '__getattr__' error
我正在尝试在 kivy 中制作游戏,但我遇到了一个问题。每当我点击“开始游戏”
我的游戏屏幕上的按钮显示
line 46, in move_ball
ball = self.root.ids.ball
File "kivy\properties.pyx", line 864, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'
我的main.py
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.image import Image
from kivy.core.audio import SoundLoader
from kivy.clock import Clock
from kivy.properties import NumericProperty
class HomeScreen(Screen):
pass
def play_sound(self):
sound = SoundLoader.load('button press sound.wav.')
if sound:
sound.play()
sound = SoundLoader.load('Crowd sound effect.wav')
sound.loop = True
sound.play()
class GameScreen(Screen):
pass
class Ball(Image):
velocity = NumericProperty(0)
def on_touch_down(self, touch):
self.source = "icons/ball1.png"
self.velocity = 275
super().on_touch_down(touch)
def on_touch_up(self, touch):
self.source = "icons/ball1.png"
super().on_touch_up(touch)
class MainApp(App):
GRAVITY = 300
def move_ball(self, time_passed):
ball = self.root.ids.ball
ball.y = ball.y + ball.velocity * time_passed
ball.velocity = ball.velocity - self.GRAVITY * time_passed
def start_game(self):
Clock.schedule_interval(self.move_ball, 1/60.)
def change_screen(self, screen_name):
# Get the screen manager from the kv file
screen_manager = self.root.ids['screen_manager']
screen_manager.current = screen_name
MainApp().run()
homescreen.kv
#:import utils kivy.utils
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
<HomeScreen>:
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#39B3F2")
Rectangle:
size: self.size
pos: self.pos
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .9
Image:
source: "icons/keepyup.png"
FloatLayout:
Button:
font_size: dp(20)
font_name: 'SackersGothicStd-Medium.otf'
text: "PLAY"
color: "gold"
pos_hint: { "center_x": .5, "center_y": .3}
size: 80, 55
size_hint: None, None
background_normal: ''
background_color: (57/255.0, 179/255.0, 242/255.0, .15)
on_press:
on_release:
root.play_sound()
root.manager.transition = FadeTransition()
app.change_screen("game_screen")
gamescreen.kv
#:import utils kivy.utils
<GameScreen>:
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#39B3F2")
Rectangle:
size: self.size
pos: self.pos
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .1
Image:
source: "icons/sun.png"
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .2
Image:
source: "icons/clouds.png"
GridLayout:
rows: 1
pos_hint: {"bottom": 1, "left": 1}
size_hint: 1, .5
Image:
source: "icons/Field4.png"
allow_stretch: True
keep_ratio: False
pos: self.pos
Button:
text: "Start game"
size_hint: None, None
on_release:
app.start_game()
Ball:
source: "icons/ball1.png"
size_hint: None, None
size: 100, 100
pos: 20, (root.height - 90) / 2.0
id: ball
main.kv
#:include kv/homescreen.kv
#:include kv/gamescreen.kv
GridLayout:
cols: 1
ScreenManager:
id: screen_manager
HomeScreen:
name: "home_screen"
id: home_screen
GameScreen:
name: "game_screen"
id: game_screen
我做了另一个 kivy 项目并在没有屏幕的情况下尝试了同样的事情,它没有显示任何错误!这是我的代码
我的main.py
from kivy.app import App
from kivy.uix.image import Image
from kivy.clock import Clock
from kivy.properties import NumericProperty
class Ball(Image):
velocity = NumericProperty(0)
def on_touch_down(self, touch):
self.source = "ball1.png"
self.velocity = 275
super().on_touch_down(touch)
def on_touch_up(self, touch):
self.source = "ball1.png"
super().on_touch_up(touch)
class MainApp(App):
GRAVITY = 300
def move_ball(self, time_passed):
ball = self.root.ids.ball
ball.y = ball.y + ball.velocity * time_passed
ball.velocity = ball.velocity - self.GRAVITY * time_passed
def start_game(self):
Clock.schedule_interval(self.move_ball, 1/60.)
MainApp().run()
main.kv
#:import utils kivy.utils
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#39B3F2")
Rectangle:
size: self.size
pos: self.pos
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .1
Image:
source: "sun.png"
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .2
Image:
source: "clouds.png"
GridLayout:
rows: 1
pos_hint: {"bottom": 1, "left": 1}
size_hint: 1, .5
Image:
source: "Field4.png"
allow_stretch: True
keep_ratio: False
pos: self.pos
Button:
text: "Start game"
size_hint: None, None
on_release:
app.start_game()
Ball:
source: "ball1.png"
size_hint: None, None
size: 100, 100
pos: 20, (root.height - 90) / 2.0
id: ball
我的第一个项目代码有什么问题?因为我的第二个似乎没有任何错误。
虽然这个问题没有完全显示回溯,但最后应该是这样的:
File "C:\Users\weebi\Desktop\TestingZone\test1\kv\homescreen.kv", line 37, in <module>
app.change_screen("game_screen")
File "C:\Users\weebi\Desktop\TestingZone\test1\main.py", line 53, in change_screen
screen_manager = self.root.ids.screen_manager
File "kivy\properties.pyx", line 964, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'
AttributeError: 'super' object has no attribute '__getattr__'
异常的原因通常与 .ids 列表中不存在的 id 有关。这是按预期工作的 change_screen
方法的更好版本:
def change_screen(self, screen_name):
self.root.current = screen_name
还修复了您的 main.kv
,以便它可以在屏幕之间正确切换
#:include kv/homescreen.kv
#:include kv/gamescreen.kv
ScreenManager:
id: screen_manager
HomeScreen:
name: "home_screen"
id: home_screen
GameScreen:
name: "game_screen"
id: game_screen
顺便说一句,虽然这与问题不一定相关,但在尝试您的代码之前,我注意到了这一行:
ball = self.root.ids.ball
我继续检查 main.kv
文件,令我惊讶的是,没有 ID 为 ball
的根小部件,但 game_screen
对象中有一个,所以我的强迫症表现不佳,我为您解决了:
def move_ball(self, time_passed):
ball = self.root.ids.game_screen.ids.ball
ball.y = ball.y + ball.velocity * time_passed
ball.velocity = ball.velocity - self.GRAVITY * time_passed
我正在尝试在 kivy 中制作游戏,但我遇到了一个问题。每当我点击“开始游戏” 我的游戏屏幕上的按钮显示
line 46, in move_ball
ball = self.root.ids.ball
File "kivy\properties.pyx", line 864, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'
我的main.py
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.image import Image
from kivy.core.audio import SoundLoader
from kivy.clock import Clock
from kivy.properties import NumericProperty
class HomeScreen(Screen):
pass
def play_sound(self):
sound = SoundLoader.load('button press sound.wav.')
if sound:
sound.play()
sound = SoundLoader.load('Crowd sound effect.wav')
sound.loop = True
sound.play()
class GameScreen(Screen):
pass
class Ball(Image):
velocity = NumericProperty(0)
def on_touch_down(self, touch):
self.source = "icons/ball1.png"
self.velocity = 275
super().on_touch_down(touch)
def on_touch_up(self, touch):
self.source = "icons/ball1.png"
super().on_touch_up(touch)
class MainApp(App):
GRAVITY = 300
def move_ball(self, time_passed):
ball = self.root.ids.ball
ball.y = ball.y + ball.velocity * time_passed
ball.velocity = ball.velocity - self.GRAVITY * time_passed
def start_game(self):
Clock.schedule_interval(self.move_ball, 1/60.)
def change_screen(self, screen_name):
# Get the screen manager from the kv file
screen_manager = self.root.ids['screen_manager']
screen_manager.current = screen_name
MainApp().run()
homescreen.kv
#:import utils kivy.utils
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
<HomeScreen>:
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#39B3F2")
Rectangle:
size: self.size
pos: self.pos
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .9
Image:
source: "icons/keepyup.png"
FloatLayout:
Button:
font_size: dp(20)
font_name: 'SackersGothicStd-Medium.otf'
text: "PLAY"
color: "gold"
pos_hint: { "center_x": .5, "center_y": .3}
size: 80, 55
size_hint: None, None
background_normal: ''
background_color: (57/255.0, 179/255.0, 242/255.0, .15)
on_press:
on_release:
root.play_sound()
root.manager.transition = FadeTransition()
app.change_screen("game_screen")
gamescreen.kv
#:import utils kivy.utils
<GameScreen>:
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#39B3F2")
Rectangle:
size: self.size
pos: self.pos
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .1
Image:
source: "icons/sun.png"
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .2
Image:
source: "icons/clouds.png"
GridLayout:
rows: 1
pos_hint: {"bottom": 1, "left": 1}
size_hint: 1, .5
Image:
source: "icons/Field4.png"
allow_stretch: True
keep_ratio: False
pos: self.pos
Button:
text: "Start game"
size_hint: None, None
on_release:
app.start_game()
Ball:
source: "icons/ball1.png"
size_hint: None, None
size: 100, 100
pos: 20, (root.height - 90) / 2.0
id: ball
main.kv
#:include kv/homescreen.kv
#:include kv/gamescreen.kv
GridLayout:
cols: 1
ScreenManager:
id: screen_manager
HomeScreen:
name: "home_screen"
id: home_screen
GameScreen:
name: "game_screen"
id: game_screen
我做了另一个 kivy 项目并在没有屏幕的情况下尝试了同样的事情,它没有显示任何错误!这是我的代码
我的main.py
from kivy.app import App
from kivy.uix.image import Image
from kivy.clock import Clock
from kivy.properties import NumericProperty
class Ball(Image):
velocity = NumericProperty(0)
def on_touch_down(self, touch):
self.source = "ball1.png"
self.velocity = 275
super().on_touch_down(touch)
def on_touch_up(self, touch):
self.source = "ball1.png"
super().on_touch_up(touch)
class MainApp(App):
GRAVITY = 300
def move_ball(self, time_passed):
ball = self.root.ids.ball
ball.y = ball.y + ball.velocity * time_passed
ball.velocity = ball.velocity - self.GRAVITY * time_passed
def start_game(self):
Clock.schedule_interval(self.move_ball, 1/60.)
MainApp().run()
main.kv
#:import utils kivy.utils
FloatLayout:
canvas:
Color:
rgb: utils.get_color_from_hex("#39B3F2")
Rectangle:
size: self.size
pos: self.pos
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .1
Image:
source: "sun.png"
GridLayout:
rows: 1
pos_hint: {"top": 1, "left": 1}
size_hint: 1, .2
Image:
source: "clouds.png"
GridLayout:
rows: 1
pos_hint: {"bottom": 1, "left": 1}
size_hint: 1, .5
Image:
source: "Field4.png"
allow_stretch: True
keep_ratio: False
pos: self.pos
Button:
text: "Start game"
size_hint: None, None
on_release:
app.start_game()
Ball:
source: "ball1.png"
size_hint: None, None
size: 100, 100
pos: 20, (root.height - 90) / 2.0
id: ball
我的第一个项目代码有什么问题?因为我的第二个似乎没有任何错误。
虽然这个问题没有完全显示回溯,但最后应该是这样的:
File "C:\Users\weebi\Desktop\TestingZone\test1\kv\homescreen.kv", line 37, in <module>
app.change_screen("game_screen")
File "C:\Users\weebi\Desktop\TestingZone\test1\main.py", line 53, in change_screen
screen_manager = self.root.ids.screen_manager
File "kivy\properties.pyx", line 964, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'
AttributeError: 'super' object has no attribute '__getattr__'
异常的原因通常与 .ids 列表中不存在的 id 有关。这是按预期工作的 change_screen
方法的更好版本:
def change_screen(self, screen_name):
self.root.current = screen_name
还修复了您的 main.kv
,以便它可以在屏幕之间正确切换
#:include kv/homescreen.kv
#:include kv/gamescreen.kv
ScreenManager:
id: screen_manager
HomeScreen:
name: "home_screen"
id: home_screen
GameScreen:
name: "game_screen"
id: game_screen
顺便说一句,虽然这与问题不一定相关,但在尝试您的代码之前,我注意到了这一行:
ball = self.root.ids.ball
我继续检查 main.kv
文件,令我惊讶的是,没有 ID 为 ball
的根小部件,但 game_screen
对象中有一个,所以我的强迫症表现不佳,我为您解决了:
def move_ball(self, time_passed):
ball = self.root.ids.game_screen.ids.ball
ball.y = ball.y + ball.velocity * time_passed
ball.velocity = ball.velocity - self.GRAVITY * time_passed