Python 属性错误:';超级';对象没有属性'__getattr';在Kivy中将BoxLayout与多个kv文件一起使用时出错
我很清楚,这个问题已经被问了好几次了。但在尝试了以下解决方案之后:Python 属性错误:';超级';对象没有属性'__getattr';在Kivy中将BoxLayout与多个kv文件一起使用时出错,python,kivy,kivy-language,Python,Kivy,Kivy Language,我很清楚,这个问题已经被问了好几次了。但在尝试了以下解决方案之后: 我已经得出结论,我需要帮助解决我的具体问题。列出的解决方案在我的具体案例中似乎不起作用 以下情况: 我目前正在尝试使用kivy为智能手机开发一个应用程序。因为我喜欢我的代码非常干净和清晰的结构,所以我将我的Kivy代码分割成几个kv文件。python代码应该主要包含逻辑,仅此而已。为了让它正常工作,我需要引用不同kv文件中不同对象的实例。为了澄清我的问题,我构建了一个相当简单的示例: 文件:trument.py fr
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.factory import Factory
from kivy.uix.label import Label
from kivy.lang import Builder
x= 1
class ComplexBox(Widget):
def testit(self):
self.ids.layout.add_widget(Label(text = "Requirement A met."))
def addsome(self):
global x
self.ids.layout.add_widget(SomeWidget(id="XXX"+str(x)))
x = x +1
pass
class SomeWidget(Widget):
def change(self):
self.ids.REQB.text = "Requirement B met."
pass
class RequirementC(Widget):
def triggerC(self):
self.ids.ERRORBUTTON.text = "Requirement C met"
pass
class Attempt(App):
def build(self):
return presentation
pass
presentation = Builder.load_file("attempt.kv")
Attempt().run()
文件:trument.kv
#:kivy 1.0
#:include attemptsupp.kv
#:include attemptsuppC.kv
# root
<ComplexBox>:
BoxLayout:
id: layout
size: root.size
Button:
id: ERRORBUTTON
text: "add"
on_press: root.addsome()
on_release: root.testit()
BoxLayout:
orientation: 'vertical'
ComplexBox:
RequirementC:
:kivy 1.0
#:包括额定电压
#:包括C.kv
#根
:
盒子布局:
id:布局
大小:root.size
按钮:
id:ERRORBUTTON
正文:“添加”
按:root.addsome()
发布时:root.testit()
盒子布局:
方向:“垂直”
ComplexBox:
要求C:
文件:attemptupp.kv
#:kivy 1.0
# rules for the widget
<SomeWidget>:
BoxLayout:
pos: root.pos
size: root.size
orientation: "vertical"
Label:
id: REQB
text: "hello"
Button:
text: "world"
on_release: root.change()
:kivy 1.0
#小部件的规则
:
盒子布局:
pos:root.pos
大小:root.size
方向:“垂直”
标签:
id:REQB
文字:“你好”
按钮:
案文:“世界”
发布时:root.change()
文件:attemptuppc.kv
#:kivy 1.0
<RequirementC>:
Button:
id: REQC
text: "Press"
on_release: root.triggerC()
:kivy 1.0
:
按钮:
id:REQC
正文:“新闻”
发布时:root.triggerC()
在kivy版本1.10和Python版本3.7.2下运行时,程序首先启动得非常好。但当我按下标有id ERRORBUTTON的“press”(按下)按钮时,我得到以下错误:
...--default --nodebug --client --host localhost --port 57777...\attempt.py "
[INFO ] [Logger ] Record log in...\.kivy\logs\kivy_19-03-15_31.txt
[INFO ] [Kivy ] v1.10.1
[INFO ] [Python ] v3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018,
...
[INFO ] [Window ] auto add sdl2 input provider
[INFO ] [Window ] virtual keyboard not allowed, single mode, not docked
[WARNING] [Lang ] attemptsupp.kv has already been included!
[WARNING] [Lang ] attemptsuppC.kv has already been included!
[INFO ] [Base ] Start application main loop
[INFO ] [GL ] NPOT texture support is available
[INFO ] [Base ] Leaving application in progress...
Traceback (most recent call last):
File "kivy\properties.pyx", line 838, in kivy.properties.ObservableDict.__getattr__
KeyError: 'ERRORBUTTON'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "...\ptvsd_launcher.py", line 45, in <module>
main(ptvsdArgs)
...
File "e:\Daten\Github_Projects\pc-clicker\attempt.py", line 35, in <module>
Attempt().run()
File "...\lib\site-packages\kivy\app.py", line 826, in run
runTouchApp()
...
File ...\lib\site-packages\kivy\lang\builder.py", line 64, in custom_callback
exec(__kvlang__.co_value, idmap)
File ...\attemptsuppC.kv", line 7, in <module>
on_release: root.triggerC()
File "...\attempt.py", line 25, in triggerC
self.ids.ERRORBUTTON.text = "Requirement C met"
File "kivy\properties.pyx", line 841, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'
…--default--nodebug--client--host localhost--port 57777…\trument.py”
[信息][记录器]记录登录…\.kivy\logs\kivy\u 19-03-15\u 31.txt
[INFO][Kivy]v1.10.1
[INFO][Python]v3.7.2(tags/v3.7.2:9A3FFC0492192018年12月23日,
...
[信息][窗口]自动添加sdl2输入提供程序
[信息][窗口]不允许使用虚拟键盘,单模,未对接
[警告][Lang]attemptupp.kv已包含在内!
[警告][Lang]attemptuppc.kv已包含在内!
[INFO][Base]启动应用程序主循环
[INFO][GL]提供NPOT纹理支持
[INFO][Base]正在退出应用程序。。。
回溯(最近一次呼叫最后一次):
文件“kivy\properties.pyx”,第838行,位于kivy.properties.observedict.\uu getattr__
KeyError:“ERRORBUTTON”
在处理上述异常期间,发生了另一个异常:
回溯(最近一次呼叫最后一次):
文件“…\ptvsd_launcher.py”,第45行,在
干管(ptvsdArgs)
...
文件“e:\Daten\Github\u Projects\pc clicker\trust.py”,第35行,在
尝试().run()
文件“…\lib\site packages\kivy\app.py”,第826行,正在运行
runTouchApp()
...
文件…\lib\site packages\kivy\lang\builder.py”,第64行,在自定义\u回调中
exec(\uuuukVLANG\uuuuuuu.co\u值,idmap)
文件…\attemptuppc.kv”,第7行,在
发布时:root.triggerC()
triggerC中第25行的文件“…\trument.py”
self.ids.ERRORBUTTON.text=“满足要求C”
文件“kivy\properties.pyx”,第841行,位于kivy.properties.observedict.\uu getattr__
AttributeError:“super”对象没有属性“\uuu getattr\uuuu”
尽管我缩短了错误消息,但应该很清楚发生了什么。我在RequirementC类中引用的ERRORBUTTON id在字典中找不到。现在来回答我的问题:
我怎样才能让它工作?我缺少什么
简而言之,我试过几件事:
- 我尝试过在屏幕中包装BoxLayouts并通过screenmanager访问它们
- 我尝试在python代码中重新排列顺序(例如,首先加载主kv文件)
- 我尝试过使用Builder工厂并在那里注册不同的类
- 我已尝试更改引用。(例如self.ids。['ERRORBUTTON']…)
我如何让我的kivy引用在不同的类中正常工作,为什么ERRORBUTTON id不在我正在查看的dict中?问题是由常见错误引起的,id与小部件有关,例如,在您的情况下,让我们分析表达式:
self.ids.ERRORBUTTON
谁是self?self是RequirementC的实例
您有什么实例?然后让我们看看.kv在哪里实现了RequirementC:
<RequirementC>:
Button:
id: REQC
text: "Press"
on_release: root.triggerC()
尝试.kv
#:kivy 1.0
#:include attemptsupp.kv
#:include attemptsuppC.kv
# root
<ComplexBox>:
error_button: ERRORBUTTON # <---
BoxLayout:
id: layout
size: root.size
Button:
id: ERRORBUTTON
text: "add"
on_press: root.addsome()
on_release: root.testit()
BoxLayout:
orientation: 'vertical'
ComplexBox:
id: complex_box
RequirementC:
on_release: complex_box.error_button.text = "Requirement C met"
#:kivy 1.0
<RequirementC>:
Button:
id: REQC
text: "Press"
on_release: root.dispatch('on_release')
:kivy 1.0
#:包括额定电压
#:包括C.kv
#根
:
error_button:ERRORBUTTON#因此,经过一点研究,我找到了我想要的答案。对于那些可能也会被我的问题绊倒的人,这里有:
class RequirementC(Widget):
def triggerC(self):
presentation.children[1].ids.ERRORBUTTON.text = "Requirement C met"
pass
通过查看演示文稿的子项,可以使用“ids”方法
但是对于那些现在想使用它的人,我建议迭代子对象以找到正确的id,而不是给出一个“硬”引用(子对象[1]).谢谢你的快速回答。在我的例子中,我的应用程序可能连接到数据库。这就是为什么我需要从python代码中按id访问按钮和标签。我希望能够动态添加新的小部件,给它们一个id,然后用python程序的不同方式操作它们。kv文件应该是我在不同的地方插入了或多或少的空模板。如果我理解正确,在kv文件中对发布操作进行了硬编码。有没有办法避免这种情况
#:kivy 1.0
<RequirementC>:
Button:
id: REQC
text: "Press"
on_release: root.dispatch('on_release')
class RequirementC(Widget):
def triggerC(self):
presentation.children[1].ids.ERRORBUTTON.text = "Requirement C met"
pass