問題描述
我很清楚,這個問題已經被問過好幾次了.但是在嘗試了以下解決方案之后:
As I am very well aware, this question has been asked several times already. But after trying the following solutions:
- Python - Kivy: AttributeError: 'super'嘗試獲取 self.ids 時對象沒有屬性__getattr__"
- Python/Kivy AttributeError: 'super' object has no屬性'__getattr__'
- 如何我可以在不獲取 AttributeError 的情況下訪問 kivy 中另一個類的對象屬性嗎:'super' object has no attribute '__getattr__'
- AttributeError: 'super' 對象沒有屬性 '__getattr__'
我已經得出結論,我需要幫助解決我的具體問題.列出的解決方案似乎不適用于我的具體情況.
I have reached the conclusion that i need help in my specific problem. The solutions listed didn't seem to work in my specific case.
以下情況:
我目前正在嘗試使用 kivy 為智能手機開發應用程序.因為我喜歡我的代碼非常干凈和清晰的結構,所以我將我的 Kivy 代碼拆分為幾個 kv 文件.python 代碼應該主要具有邏輯,僅此而已.為了讓它正常工作,我需要在不同的 kv 文件中引用不同對象的實例.為了讓我的問題更清楚,我構建了一個相當簡單的例子:
I am currently trying to develop an application for smartphones using kivy. Since i like my code pretty clean and clear structured i have split my Kivy code into several kv-files. The python code is supposed to have primarily the logic and nothing more. In order to get it working properly i need to reference the instances of the different objects in the different kv-files. In order to make my problem clear i have constructed a fairly simple example:
文件:嘗試.py
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()
文件:嘗試.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:
文件:attemptsupp.kv
FILE: attemptsupp.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()
文件:attemptsuppC.kv
FILE: attemptsuppC.kv
#:kivy 1.0
<RequirementC>:
Button:
id: REQC
text: "Press"
on_release: root.triggerC()
正在運行的程序的圖片 - 按Press"- 按鈕得到錯誤一個>
使用 kivy 1.10 版和 Python 3.7.2 版運行,該程序首先可以正常啟動.但是,當我按下標有按下"且 ID 為 ERRORBUTTON 的按鈕時,出現此錯誤:
Running with kivy version 1.10 and Python version 3.7.2 the program first starts perfectly fine. But when I press on the Button labeled "press" with the id ERRORBUTTON I get this error:
...--default --nodebug --client --host localhost --port 57777...attempt.py "
[INFO ] [Logger ] Record log in....kivylogskivy_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 "kivyproperties.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:DatenGithub_Projectspc-clickerattempt.py", line 35, in <module>
Attempt().run()
File "...libsite-packageskivyapp.py", line 826, in run
runTouchApp()
...
File ...libsite-packageskivylanguilder.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 "kivyproperties.pyx", line 841, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'
即使我縮短了錯誤消息,也應該清楚發生了什么.在字典中找不到我在 RequirementC 類中引用的 ERRORBUTTON id.現在回答我的問題:
Even though I shortened the error message it should be clear what happens. The ERRORBUTTON id I am referencing in the RequirementC Class can't be found in the dictionary. Now to my question:
我怎樣才能讓它工作?我缺少什么?
How can i make it work? What am I a missing?
簡而言之,我嘗試了幾件事:
Here in short a few things i have tried:
- 我嘗試將 BoxLayouts 包裝在 Screen 中并通過 screenmanager 訪問它們.
- 我嘗試在 python 代碼中重新排列順序.(例如先加載主kv文件)
- 我嘗試過使用 Builder Factory 并在那里注冊不同的類.
- 我已嘗試更改參考.(例如 self.ids.['ERRORBUTTON']...)
這些嘗試對我來說似乎都沒有奏效.
None of these attempts seem to have worked in my case.
總結一下:
如何讓不同類的 kivy 引用正常工作,為什么 ERRORBUTTON id 不在我正在查看的字典中?
How can I get my kivy References across different classes to work properly and why is the ERRORBUTTON id not in the dict I am looking into?
推薦答案
所以經過一番研究,我找到了我想要的答案.對于那些可能也會偶然發現我的問題的人來說:
So after a bit of research i found the answer i was looking for. For those who might also stumble over my problem here it comes:
class RequirementC(Widget):
def triggerC(self):
presentation.children[1].ids.ERRORBUTTON.text = "Requirement C met"
pass
通過查看演示文稿的子項,可以使用ids"方法.
By going over the children of the presentation it is possible to use the "ids" method.
但對于那些想現在使用它的人,我建議遍歷孩子以找到正確的 id,而不是給出硬"參考(孩子 [1]).
But for those tempted to use it now i would recommend iterating over the children to find the correct id instead of giving a "hard" reference (children[1]).
這篇關于AttributeError: 'super' object has no attribute '__getattr__' 在 Kivy 中使用帶有多個 kv 文件的 BoxLayout 時出錯的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!