Цель
Я хочу создать небольшой скрипт, который динамически добавляет кнопки, но все же позволяет мне выполнять функции для определенных из них через root.
Мои методы
Я сделал этот скрипт.
Он способен динамически добавлять большие кнопки вдоль верхней части.
Каждая из этих кнопок при нажатии слегка меняет свой цвет.
Он имеет две маленькие кнопки внизу.
Первая кнопка динамически добавляет новые большие кнопки вверху.
Вторая кнопка сбрасывает цвет первой большой кнопки сверху.
Мой код
#!/usr/bin/env python3
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
Builder.load_string('''
<RootWidget>:
Button:
text: 'Add'
size_hint: (None, None)
size: (40, 40)
pos: (40, 40)
group: 'action'
on_press: root.createNextTarget()
Button:
text: 'res'
size_hint: (None, None)
size: (40, 40)
pos: (100, 40)
group: 'action'
on_press: root.resetTarget()
''')
class RootWidget(FloatLayout):
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
#note: self.ids isn't populated yet. I guess we can't use it yet.
self.createNextTarget()
def resetTarget(self):
f_target = self.ids['targetbutton0']
f_target.background_color = (1.0, 1.0, 1.0, 1.0)
return True
def countTargets(self):
return [str(x.__class__.__name__) for x in self.children if x != None].count('TargetButton')
def createNextTarget(self):
f_nextButton = TargetButton(id="targetbutton"+str(self.countTargets()),
size_hint=(None, None),
pos=(80 + (10 + 60) * self.countTargets(), 100),
size=(60, 60),
background_normal = '',
background_color = (1, 1, 1, 1),
group = 'target')
self.add_widget(f_nextButton)
f_nextButton.bind(on_press=TargetButton.lowerAllRGB)
class TargetButton(Button):
def __init__(self, **kwargs):
super(TargetButton, self).__init__(**kwargs)
def lowerAllRGB(self):
f_r, f_g, f_b, f_a = self.background_color
if f_r >= 0.1: f_r = f_r - 0.1
if f_g >= 0.1: f_g = f_g - 0.1
if f_b >= 0.1: f_b = f_b - 0.1
self.background_color = (f_r, f_g, f_b, f_a)
return True
class TestApp(App):
def build(self):
return RootWidget()
def on_stop(self):
print("TestApp.on_stop: finishing", self.root.ids)
if __name__ == '__main__':
TestApp().run()
Проблема
Если я пытаюсь нажать кнопку сброса (которая получает доступ к виджету через root.ids
), я получаю ошибку: KeyError: 'targetbutton0'
После нахождения сообщения о подобной проблеме я подумал, что root.ids
просто не будет работать во время RootWidget.__init__
.
Но когда я использую кнопку для добавления кнопок после RootWidget.__init__
,готово, TestApp.on_stop()
по-прежнему печатает: TestApp.on_stop: finish {}
Так что root.ids
все еще пусто и, похоже, не содержит никаких динамически добавленных виджетов, несмотря на то, что я назначил атрибут id каждому из них.
Мои вопросы к вам
- Учитывая то, как я динамически добавляю виджеты, использование
root.ids
просто бесполезно для моих целей? - Есть ли для меня достойный способ доступа к моим виджетам через id?
Я видел другой вопрос hпрежде чем просить что-то подобное.Но он не ответил на мой вопрос о динамически добавляемых виджетах.