I am having trouble accessing dynamically created children via root.ids.created_in_kv.created_in_py in method bound to button. When I check root.ids.created_in_kv.ids dictionary it is empty, but there are children in root.ids.created_in_kv.children
What I'm trying to achieve is to create a popup that will act as multiselector. It will accept possible choices and dynamically create label-checkbox pair and add it to popup contents, and on 'Apply' button it will return only chosen list(str()).
I can't constuct popup with multiple widgets in it in kv, but the following works (suggestions to make it 'nicer' more than welcome):
kv code:
<SelectorPopup>:
title: 'empty'
BoxLayout:
id: inside
orientation: 'vertical'
BoxLayout:
id: options
BoxLayout:
id: buttons
orientation: 'vertical'
Button:
text: 'Apply'
on_release: root.return_selected()
Button:
text: 'Cancel'
on_release: root.dismiss()
<LabeledCheckbox@BoxLayout>:
id: entity
CheckBox:
id: choice
Label:
text: root.id
And the python code I'm creating the label-checkbox pairs (packaged in GridLayout) and putting it into options BoxLayout :
class SelectorPopup(Popup):
def return_selected(self):
selected=[]
a = self.ids.inside.options.choices.ids # dict is empty
for item in a.keys():
selected.append(item) if a[item].ids.choice.value #add if checkbox checked
return selected
class MultiselectForm(BoxLayout):
data = ListProperty([])
def __init__(self, **kwargs):
super(MultiselectForm, self).__init__(**kwargs)
self.prompt = SelectorPopup()
def apply_data(self):
# write data to self.data
pass
def create_popup(self):
try:
# some code to check if choices are already created
check = self.prompt.ids.inside.options.choices.id
except AttributeError:
possible = ['choice1','choice2','choice3'] #query db for possible instances
choices = GridLayout(id='choices',cols=2)
for entity in possible:
choice = Factory.LabeledCheckbox(id=entity)
choices.add_widget(choice)
self.prompt.ids.options.add_widget(choices)
self.prompt.open()
Questions:
1) Howto make return_selected method work?
2) Is there a way to construct popup more nicely? I can't add widget tree into content ObjectProperty like:
<MyPopup>:
content:
BoxLayout:
Label:
text: 'aaa'
Label:
text: 'bbb'
It looks like you're a little mixed up on how ids work. They are talked about a little bit in the docs: https://kivy.org/docs/api-kivy.lang.html
Basically, they are just special tokens in .kv
that lets you reference defined widgets. They are collected and placed in the ids
dictionary on the root widget of the rule they are defined in. This means they aren't nested like you are referencing them, they are all on the root widget ( SelectorPopup
or LabeledCheckbox
)
So instead of (from within SelectorPopup
):
self.ids.inside.options.choices
You would have:
self.ids.choices
This also means that widgets added dynamically aren't going to be present in the ids
dictionary, but they don't really need to be. Since you are creating them in code, you can just save references to them yourself (which is harder to do with .kv
).
All that being said, it might be a lot easier to use a ListView to display your list of items.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.