问题描述
我无法通过 root.ids.created_in_kv.created_in_py 在绑定到按钮的方法中访问动态创建的子项.当我检查 root.ids.created_in_kv.ids 字典时它是空的,但是 root.ids.created_in_kv.children
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
我想要实现的是创建一个充当多选器的弹出窗口.它将接受可能的选择并动态创建标签-复选框对并将其添加到弹出内容中,并且在应用"按钮上它将仅返回选择的列表(str()).
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()).
我无法在 kv 中构建包含多个小部件的弹出窗口,但以下工作(建议使其更好"而不是受欢迎):
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代码:
<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
我正在创建标签-复选框对(打包在 GridLayout 中)并将其放入 options BoxLayout 的 python 代码:
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()
问题:
1) 如何使 return_selected 方法起作用?
1) Howto make return_selected method work?
2) 有没有办法更好地构建弹出窗口?我无法将小部件树添加到 content ObjectProperty 中,例如:
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'
推荐答案
看起来你对 ids 的工作方式有点混淆.文档中对它们进行了一些讨论:https://kivy.org/docs/api-kivy.lang.html
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
基本上,它们只是 .kv
中的特殊标记,可让您引用已定义的小部件.它们被收集并放置在定义它们的规则的ids
字典根小部件中.这意味着它们不像您引用它们那样嵌套,它们是所有在根窗口小部件上(SelectorPopup
或 LabeledCheckbox
)
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
)
所以而不是(从 SelectorPopup
中):
So instead of (from within SelectorPopup
):
self.ids.inside.options.choices
你会:
self.ids.choices
这也意味着动态添加的小部件不会出现在 ids
字典中,但它们实际上并不需要.由于您是在代码中创建它们,因此您可以自己保存对它们的引用(使用 .kv
更难做到这一点).
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
).
话虽如此,使用 ListView 显示您的项目列表.
All that being said, it might be a lot easier to use a ListView to display your list of items.
这篇关于引用 Kivy 中动态创建的小部件的 id的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!