python - 无法从 kivy 文件访问特定 id 到我的 python 错误“AttributeError:'super' object has no attribute '__getattr__'”
问题描述
主要代码 <main.py>
import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.core.window import Window
from kivy.clock import Clock
from kivy.uix.behaviors import ButtonBehavior
class Background(Widget):
cloud_texture = ObjectProperty(None)
tree1_texture = ObjectProperty(None)
tree2_texture = ObjectProperty(None)
grass_texture = ObjectProperty(None)
bush_texture = ObjectProperty(None)
def __init__(self,**kwargs):
super().__init__(**kwargs)
self.cloud_texture = Image(source="cloud.png").texture
self.cloud_texture.wrap = 'repeat'
self.cloud_texture.uvsize = (Window.width/ self.cloud_texture.width, -1)
self.tree1_texture = Image(source="tree_1.png").texture
self.tree1_texture.wrap = 'repeat'
self.tree1_texture.uvsize = (Window.width/ self.tree1_texture.width, -1)
self.tree2_texture = Image(source="tree_2.png").texture
self.tree2_texture.wrap = 'repeat'
self.tree2_texture.uvsize = (Window.width/ self.tree2_texture.width, -1)
self.grass_texture = Image(source="grass.png").texture
self.grass_texture.wrap = 'repeat'
self.grass_texture.uvsize = (Window.width/ self.grass_texture.width, -1)
self.bush_texture = Image(source="bush.png").texture
self.bush_texture.wrap = 'repeat'
self.bush_texture.uvsize = (Window.width/ self.bush_texture.width, -1)
def on_size(self, *args):
self.cloud_texture.uvsize = (self.width / self.cloud_texture.width, -1)
self.tree1_texture.uvsize = (self.width / self.tree1_texture.width, -1)
self.tree2_texture.uvsize = (self.width / self.tree2_texture.width, -1)
self.grass_texture.uvsize = (self.width / self.grass_texture.width, -1)
self.bush_texture.uvsize = (self.width / self.grass_texture.width, -1)
def scroll_textures(self, time_passed):
self.cloud_texture.uvpos = ((self.cloud_texture.uvpos[0] + time_passed/8.0)% Window.width , self.cloud_texture.uvpos[1])
self.tree1_texture.uvpos = ((self.tree1_texture.uvpos[0] + time_passed/2.0)% Window.width , self.tree1_texture.uvpos[1])
self.tree2_texture.uvpos = ((self.tree2_texture.uvpos[0] + time_passed/2.0)% Window.width , self.tree2_texture.uvpos[1])
self.grass_texture.uvpos = ((self.grass_texture.uvpos[0] + time_passed/8.0)% Window.width , self.grass_texture.uvpos[1])
self.bush_texture.uvpos = ((self.bush_texture.uvpos[0] + time_passed/8.0)% Window.width , self.bush_texture.uvpos[1])
texture = self.property('cloud_texture')
texture.dispatch(self)
texture = self.property('tree1_texture')
texture.dispatch(self)
texture = self.property('tree2_texture')
texture.dispatch(self)
texture = self.property('grass_texture')
texture.dispatch(self)
texture = self.property('bush_texture')
texture.dispatch(self)
print("scroll")
pass
def on_stop(self):
pass
class StartWindow(Screen):
def __init__(self, **kwargs):
super(StartWindow,self).__init__(**kwargs)
pass
class GameWindow(Screen):
def __init__(self, **kwargs):
super(GameWindow,self).__init__(**kwargs)
pass
class OptionsWindow(Screen):
def __init__(self, **kwargs):
super(OptionsWindow,self).__init__(**kwargs)
pass
class WindowManager(ScreenManager):
pass
class MainApp(App):
def __getattr__(self, attr):
return super().__getattr__(attr)
def on_start(self):
Clock.schedule_interval(self.root.ids.background.scroll_textures,1/60.)
pass
MainApp().run()
“Clock.schedule_interval(g.ids.background.scroll_textures,1/60.)”行不工作。我不了解从 kv 文件调用 id 的基本方法。
main.kv 文件
WindowManager:
StartWindow:
GameWindow:
OptionsWindow:
<StartWindow>:
name: "start"
id: startwindow
FloatLayout:
cols:4
Image:
source: 'Flying_whale.png'
allow_stretch: True
keep_ratio: False
Button:
pos_hint:{"x":0,"y":0.50}
background_color: 0,0,0,0
color: 0,0,0,1
size_hint: 0.4, 0.1
font_size: (root.width**2 + root.height**2) / 17**3.3
text: "Start!"
id: set_event
on_press:
root.manager.transition.direction = "down"
root.on_start()
Button:
pos_hint:{"x":0.15,"y":0.25}
background_color: 0,0,0,0
color: 0,0,0,1
size_hint: 0.4, 0.1
font_size: (root.width**2 + root.height**2) / 17**3.5
text: "Options"
on_release:
root.manager.transition.direction = "right"
app.root.current = "options"
Button:
pos_hint:{"x":0.15,"y":0.10}
background_color: 0,0,0,0
color: 0,0,0,1
size_hint: 0.4, 0.1
font_size: (root.width**2 + root.height**2) / 17**3.5
text: "Exit"
<GameWindow>
name:"game"
id: gamewindow
FloatLayout:
Background:
id: background
canvas.before:
Rectangle:
size: self.size
pos: self.pos
source: "sky.png"
Rectangle:
size: self.width, 150
pos: self.pos[0],self.pos[1] + self.height - 138
texture: self.cloud_texture
Rectangle:
size: self.width, 160
pos: self.pos[0],self.pos[1]
texture: self.grass_texture
Rectangle:
size: self.width, 100
pos: self.pos[0]-10,self.pos[1] + 145
texture: self.tree1_texture
Rectangle:
size: self.width, 100
pos: self.pos[0]+30,self.pos[1] + 160
texture: self.tree2_texture
Rectangle:
size: self.width, 20
pos: self.pos[0],self.pos[1] + 155
texture: self.bush_texture
Label:
id: score
size_hint_y : None
height : 96
text: "0"
font_size: 40
Button:
pos_hint:{"x":0,"y":0.25}
background_color: 0,0,0,0
color: 0,0,0,1
size_hint: 0.4, 0.1
font_size: (root.width**2 + root.height**2) / 17**3.3
text: "Back"
id: set_event
on_release:
<OptionsWindow>:
name: "options"
FloatLayout:
cols:4
Image:
source: 'Flying_whale.png'
allow_stretch: True
keep_ratio: False
Button:
pos_hint:{"x":0.15,"y":0.20}
background_color: 0,0,0,0
color: 0,0,0,1
size_hint: 0.4, 0.1
font_size: (root.width**2 + root.height**2) / 17**3.5
text: "Back"
on_release:
root.manager.transition.direction = "left"
app.root.current = "start"
Button:
pos_hint:{"x":0.15,"y":0.35}
background_color: 0,0,0,0
color: 1,1,1,1
size_hint: 0.4, 0.1
font_size: (root.width**2 + root.height**2) / 17**3.5
text: "Mode : Night / Day"
错误由下式给出:
AttributeError:“超级”对象没有属性“ getattr ”
我知道这是一个简单的理解问题,但我无法解决它。谢谢
解决方案
问题是是在规则中id: background
定义的。根据文档:GameWindow
kv
当处理 kv 文件时,所有带有 id 标记的小部件的弱引用被添加到根小部件的 ids 字典中。
虽然该术语root widget
被过度使用并且根据上下文具有不同的含义,但这里它的意思rule
是包含id
. 所以background
id
只会出现在ids
小GamWindow
部件的。
知道了这一点,您有问题的代码行可以替换为:
Clock.schedule_interval(self.root.get_screen('game').ids.background.scroll_textures,1/60.)
上面的代码用于get_screen()
访问GameWindow
.
推荐阅读
- r - 如何在 igraph 中连接图形的组件
- css - 为什么一旦需要垂直滚动条,Firefox 会添加水平滚动条?
- angular - 添加和删除列内联编辑不起作用
- php - 通过 docker pull wordpress 将 wordpress 5.6.2 更新到 5.7 后,管理员中的 php-error 正文类
- react-native - 在 React Native WebView 中添加 Android 上的自定义选择菜单
- ios - Xamarin.iOS:UIAlertController 不会禁用其他 UIBarButtonItem
- c# - 使用jquery将数据从视图传递到控制器
- pdb - 使用 MDAnalysis 从 pdb 中提取数组中的坐标
- svelte - 我应该如何使用汇总构建两个苗条页面?
- swiftui - 动画突然结束。我怎样才能使这个顺利?