在Kivy中引用动态创建的窗口小部件的ID [英] Referencing id of dynamically created widget in Kivy

查看:263
本文介绍了在Kivy中引用动态创建的窗口小部件的ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法通过绑定到button的方法中的 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

然后我要创建python-checkbox对(包装在GridLayout中)并将其放入 options BoxLayout

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'

推荐答案

您似乎对id的工作方式有些困惑.他们在文档中讨论了一些内容: 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词典 中.这意味着它们不像您引用它们时嵌套,它们都在根窗口小部件上(SelectorPopupLabeledCheckbox)

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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆