Как мне хорошо известно, этот вопрос уже задавался несколько раз. Но попробовав следующие решения:
Я пришел к выводу, что мне нужна помощь в решении моей конкретной проблемы. Перечисленные решения не работают в моем конкретном случае.
Следующая ситуация:
В настоящее время я пытаюсь разработать приложение для смартфонов, используя kivy. Поскольку мне нравится мой код, довольно чистый и ясный, я разделил код на Kivy на несколько kv-файлов. Предполагается, что код Python должен иметь в первую очередь логику и ничего более. Чтобы заставить его работать должным образом, мне нужно сослаться на экземпляры разных объектов в разных kv-файлах. Чтобы прояснить мою проблему, я построил довольно простой пример:
ФАЙЛ: try.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()
ФАЙЛ: try.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
# 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()
ФАЙЛ: попытки открытия файла.kv
#:kivy 1.0
<RequirementC>:
Button:
id: REQC
text: "Press"
on_release: root.triggerC()
изображение запущенной программы - нажмите кнопку «Нажать» - чтобы получить ошибку
При запуске с kivy версии 1.10 и Python версии 3.7.2 программа сначала запускается идеально. Но когда я нажимаю на кнопку с надписью 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__'
Даже если я сократил сообщение об ошибке, должно быть ясно, что происходит. ОШИБКА ID, на которую я ссылаюсь в классе RequirementC, не найдена в словаре. Теперь на мой вопрос:
Как я могу заставить это работать? Что мне не хватает?
Вот вкратце несколько вещей, которые я попробовал:
- Я попытался обернуть BoxLayouts в Screen и получить к ним доступ через менеджер экрана.
- Я попытался изменить порядок в коде Python. (например, сначала загрузка основного файла kv)
- Я попытался использовать Фабрику Строителей и зарегистрировать там разные Классы.
- Я попытался изменить ссылки. (Например, self.ids. ['ERRORBUTTON'] ...)
Ни одна из этих попыток, похоже, не сработала в моем случае.
Итак, подведем итог:
Как я могу заставить мои kivy References из разных классов работать должным образом и почему идентификатор ERRORBUTTON не входит в диктовку, которую я изучаю?