在 TabbedPanel 中获取小部件/项目 ID [关闭]

Posted

技术标签:

【中文标题】在 TabbedPanel 中获取小部件/项目 ID [关闭]【英文标题】:Getting widget/item ids within TabbedPanel [closed] 【发布时间】:2019-08-29 09:15:12 【问题描述】:

我在 Kivy 中创建了一个带有选项卡的简单应用程序,并且在每个选项卡中我只有几个小部件。在添加 tabbedPanel 之前,我通过“ids”访问每个小部件没有问题。例如:

app.root.ids.mylabel1.ids.mylabel2.content

但是,现在我在 tabbedPanel 中添加了小部件,它们对我来说变得无法访问。 tabbedPanel “阻止”我并且不包含任何 ID:例如,我的 .kv 文件有一个按钮:

<SelectableButton>:
    text: self.button_text
    id: SelectableButton_id
    canvas.before:
        Color:
            rgba: (0, 0.517, 0.705, 1) if self.selected else (0, 0.517, 0.705, 1)
        Rectangle:
            pos: self.pos
            size: self.size
    state: self.btnState
    on_release:
        print(app.root.content.ids)

返回一个空字典。我按照 tabbedPanel 的指导,发现它只有一个“孩子”,即“.content”。但我仍然无法访问此选项卡中的任何小部件。

我是不是走错了路?或者任何人都可以指导我如何访问特定选项卡中的小部件。

【问题讨论】:

【参考方案1】:

使用 Kivy TabbedPanel,您可以使用 app.root.ids.id-nameself.ids.id-name 引用 ids,例如app.root.ids.label3.textself.ids.label3.text 因为当你的 kv 文件被解析时,kivy 会收集所有带有 id's 标记的小部件并将它们放在这个 self.ids 字典类型属性中。

示例

main.py

​​>
from kivy.app import App
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.button import Button

Builder.load_string("""

<Test>:
    size_hint: .5, .5
    pos_hint: 'center_x': .5, 'center_y': .5
    do_default_tab: False

    TabbedPanelItem:
        text: 'first tab'
        Label:
            text: 'First tab content area'

    TabbedPanelItem:
        id: tab2
        text: 'tab2'

        BoxLayout:
            id: box1
            orientation: 'vertical'

            Label:
                id: label1
                text: 'Second tab content area'
            Button:
                id: button1
                text: 'Button that does nothing'

            BoxLayout:
                id: box2
                orientation: 'vertical'

                Label:
                    id: label2
                    text: 'Label 2'

                BoxLayout:
                    id: box3
                    orientation: 'vertical'

                    Button:
                        id: button2
                        text: 'Button 2'
                    Label:
                        id: label3
                        text: 'Label 3'

    TabbedPanelItem:
        text: 'tab3'
        RstDocument:
            text:
                '\\n'.join(("Hello world", "-----------",
                "You are in the third tab."))

""")


class Test(TabbedPanel):

    def __init__(self, **kwargs):
        super(Test, self).__init__(**kwargs)
        print(f"\nself.ids.items():")
        for key, val in self.ids.items():
            if isinstance(val, Label) or isinstance(val, Button):
                print(f"\tkey=key, val=val, val.text=val.text")
            else:
                print(f"\n\tkey=key, val=val")

        print(f"\nself.ids.label3.text=self.ids.label3.text")


class TabbedPanelApp(App):
    def build(self):
        return Test()


if __name__ == '__main__':
    TabbedPanelApp().run()

输出

【讨论】:

感谢您的回复。可悲的是,我很快意识到我的问题与 id 无关,而是我每次尝试调用其中一个类时都会不断创建新的类对象这一事实。这是我遇到的一个更广泛的问题。理想情况下,我希望在启动应用程序时创建类对象。之后,我将这些类对象称为该模块中的“全局变量”。这是我第一次创建一个小应用程序因此感到困惑。我想问题应该是“我如何为每个类创建一个类对象,然后将该对象用于该类中的所有所需活动。 请提供最少的代码,包括 TabbedPanel 和重现问题的步骤。 我解决了,我几乎想删除这篇文章,因为它与实际问题无关。但是感谢您的参与,它确实帮助我找到了问题,即我多次创建新的类对象,因为我没有在哪里启动我的类。我的解决方案是在 build() ass Objectproperties 下创建类对象。例如: self.class_object1 = my_custom_class() 在 build 方法中定义。因此 self.class_object1 可以在 App 属性下通过我的 App 访问。 如果我的回答对您的项目有一些帮助,请接受回答。谢谢。

以上是关于在 TabbedPanel 中获取小部件/项目 ID [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何在事件中获取小部件名称

如何从滚动文本小部件中获取文本?

流不重建小部件

获取组件(窗口小部件)中相应的redux存储状态更新的数据

如何在android中获取主屏幕小部件列表项的点击事件[重复]

Android在小部件内获取textView值