我很清楚,这个问题已经被问了好几次了。但在尝试了以下解决方案后:
我已经得出结论,在我的具体问题上我需要帮助。列出的解决方案在我的具体案例中似乎不起作用。在
以下情况:
我目前正在尝试使用kivy为智能手机开发一个应用程序。因为我喜欢我的代码相当干净和清晰的结构,我把我的Kivy代码分成了几个kv文件。python代码应该主要有逻辑,没有更多。为了让它正常工作,我需要引用不同kv文件中不同对象的实例。为了使我的问题更清楚,我构建了一个相当简单的例子:
文件:尝试.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在
^{pr2}$文件:备用千伏在
^{3}$文件:备用电压,kv在
#:kivy 1.0
<RequirementC>:
Button:
id: REQC
text: "Press"
on_release: root.triggerC()
picture of the Running Program - press the "Press"- button to get the error
在kivy1.10版和python3.7.2版上运行时,该程序第一次启动非常顺利。但是当我按下带有id error按钮的“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__'
尽管我缩短了错误信息,但应该很清楚发生了什么。在字典中找不到我在RequirementC类中引用的ERRORBUTTON id。现在来回答我的问题:
我该怎么做?我失踪了什么?在
简而言之,我尝试了以下几点:
这些尝试对我来说似乎都没有奏效。在
所以总结一下:
如何让我的kivy引用跨不同的类正常工作,为什么ERRORBUTTON id不在我要查看的dict中?在
这个问题是由一个常见错误引起的,id是相对于一个widget的,例如在您的例子中,让我们分析一下表达式:
谁是自我?self是RequirementC的实例。在
你有什么例子?然后让我们看看.kv,其中实施了RequirementC:
^{pr2}$如果您注意到唯一可以访问REQC的id,那么对于RequirementC,id error按钮不存在。在
那么id ERRORBUTTON属于哪个类?让我们回顾一下ERRORBUTTON的创建位置:
如您所见,ERRORBUTTON是ComplexBox的id。在
根据上一部分所提到的,我们已经知道问题的原因了。在给出解决方案之前,我们首先要理解编程的一个基本原则:类是一个行为的抽象,它必须清楚地定义你想对外公开(因此,如果你检查任何库的文档,不要记录所有的方法或所有的类,因为这样做的目的是抽象类,也就是说,不管是谁使用这个库,都不想知道它是如何以如此高的精度在内部工作的),所以在设计时最好考虑类将具有什么方法。例如,假设我们创建了一个Person类,这个类有一些属性,比如大小或者重量,如果你认为有必要公开你的心脏或者大脑的重量呢?你的情况也一样。在
解决方案是在_release上公开事件,使其成为RequirementC类的一部分,此外还将ERRORBUTTON作为属性公开(在我的例子中,我不喜欢使用id,因为它们使代码的可读性降低),然后在具有公共作用域的地方建立连接。在
*.py
尝试.kv
备用电压,kv
所以经过一番研究,我找到了我想要的答案。对于那些可能也会被我的问题绊倒的人来说:
通过检查演示文稿的子级,可以使用“ids”方法。在
但是对于那些现在想使用它的人,我建议迭代子对象以找到正确的id,而不是给出一个“硬”引用(children[1])。在
相关问题 更多 >
编程相关推荐