在 Kivy 中引用动态创建的小部件的 id
Referencing id of dynamically created widget in Kivy
我无法通过绑定到按钮的方法中的 root.ids.created_in_kv.created_in_py 访问动态创建的 children。当我检查 root.ids.created_in_kv.ids 字典时它是空的,但是 root.ids.created_in_kv.children[=13 中有 children =]
我想要实现的是创建一个将充当多选器的弹出窗口。它将接受可能的选择并动态创建 label-checkbox 对并将其添加到弹出内容中,并且在 'Apply' 按钮上它将 return 仅选择 list(str()).
我无法在 kv 中构造带有多个小部件的弹出窗口,但以下工作(使它 'nicer' 更受欢迎的建议):
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
我正在创建 label-checkbox 对的 python 代码(打包在 GridLayout 中)并将其放入 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 方法起作用?
2) 有没有更好的popup构造方法?我无法将小部件树添加到 content ObjectProperty 中,例如:
<MyPopup>:
content:
BoxLayout:
Label:
text: 'aaa'
Label:
text: 'bbb'
您似乎对 ID 的工作方式有点困惑。文档中对它们进行了一些讨论:https://kivy.org/docs/api-kivy.lang.html
基本上,它们只是 .kv
中的特殊标记,可让您引用定义的小部件。它们被收集并放置在 ids
字典中 在它们定义的规则的根小部件 上。这意味着它们不像您引用它们那样嵌套,它们是全部在根小部件上(SelectorPopup
或 LabeledCheckbox
)
所以而不是(来自 SelectorPopup
):
self.ids.inside.options.choices
你会:
self.ids.choices
这也意味着动态添加的小部件不会出现在 ids
字典中,但它们实际上并不需要。由于您是在代码中创建它们,因此您可以自己保存对它们的引用(使用 .kv
更难做到)。
综上所述,使用 ListView 显示项目列表可能会容易得多。
我无法通过绑定到按钮的方法中的 root.ids.created_in_kv.created_in_py 访问动态创建的 children。当我检查 root.ids.created_in_kv.ids 字典时它是空的,但是 root.ids.created_in_kv.children[=13 中有 children =]
我想要实现的是创建一个将充当多选器的弹出窗口。它将接受可能的选择并动态创建 label-checkbox 对并将其添加到弹出内容中,并且在 'Apply' 按钮上它将 return 仅选择 list(str()).
我无法在 kv 中构造带有多个小部件的弹出窗口,但以下工作(使它 'nicer' 更受欢迎的建议):
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
我正在创建 label-checkbox 对的 python 代码(打包在 GridLayout 中)并将其放入 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 方法起作用?
2) 有没有更好的popup构造方法?我无法将小部件树添加到 content ObjectProperty 中,例如:
<MyPopup>:
content:
BoxLayout:
Label:
text: 'aaa'
Label:
text: 'bbb'
您似乎对 ID 的工作方式有点困惑。文档中对它们进行了一些讨论:https://kivy.org/docs/api-kivy.lang.html
基本上,它们只是 .kv
中的特殊标记,可让您引用定义的小部件。它们被收集并放置在 ids
字典中 在它们定义的规则的根小部件 上。这意味着它们不像您引用它们那样嵌套,它们是全部在根小部件上(SelectorPopup
或 LabeledCheckbox
)
所以而不是(来自 SelectorPopup
):
self.ids.inside.options.choices
你会:
self.ids.choices
这也意味着动态添加的小部件不会出现在 ids
字典中,但它们实际上并不需要。由于您是在代码中创建它们,因此您可以自己保存对它们的引用(使用 .kv
更难做到)。
综上所述,使用 ListView 显示项目列表可能会容易得多。