在Kivy(kv语言)中使用id引用小部件

3
我有以下 KV 语言代码(简化示例): 我的问题出在最后一行(on_release)。
(注:KV 语言是用于构建 Python Kivy 应用程序界面的声明性语言)
#:import Factory kivy.factory.Factory

<MyCustomWidgets>:
    
    ListView:
        id: my_listview
    
    
<MainScreen>:
    
    Button:
        text: "Choose File"
        on_release: Factory.FileChooserDialog().open()
    
    MyCustomWidgets:
            
    
<FileChooserDialog@ModalView>:
    
    FileChooserIconView:
        id: filechooser

    Button:
        text: "OK"
        on_release: app.root.add_to_listview("Sample Text", app.root.ids.my_listview)

在Python中,我有:
class MainScreen(BoxLayout):
    def add_to_listview(self, thelistview):
        # For testing purposes.
        print(type(thelistview))

在KV语言中,我正在尝试运行一个Python方法,该方法将一个字符串添加到id为my_listviewListView中,但出现了此错误:
AttributeError: 'super' object has no attribute '__getattr__'

我不理解这个例子,为什么这些规则要缩进?它们为什么要有id呢?对于一个规则来说,拥有id是没有意义的,因为ids只在规则内部有效。 - Tshirtman
@Tshirtman:idents 是一个错误,我已经修复了示例,并仅在必要的地方放置了 id。我基本上想将所选路径/文件名添加到 ListView(从 filechooser),但我不确定如何访问 ListView。 - garlic
1个回答

3

使用 Kivy 的 ObjectPropertymy_listview = ObjectProperty(None) 并将其连接 (my_listview: my_listview) 到 kv 文件中定义的 id: my_listview。请参考示例和输出以获取详细信息。

示例

main.py

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty


class MyCustomWidgets(BoxLayout):
    my_listview = ObjectProperty(None)


class MainScreen(BoxLayout):

    def add_to_listview(self, *args, thelistview):
        # For testing purpose
        print(self)
        print(args[0])
        print(thelistview)


class TestApp(App):
    title = "Reference widget using id in Kivy (kv language)"

    def build(self):
        return MainScreen()


if __name__ == "__main__":
    TestApp().run()

test.kv

#:kivy 1.10.0
#:import Factory kivy.factory.Factory


<MyCustomWidgets>:
    my_listview: my_listview
    ListView:
        id: my_listview


<MainScreen>:
    orientation: "vertical"

    Button:
        text: "Choose File"
        on_release: Factory.FileChooserDialog().open()

    MyCustomWidgets:
        id: my_cw


<FileChooserDialog@ModalView>:

    id: filechooser

    Button:
        text: "OK"
        on_release:
            app.root.add_to_listview("Sample Text", thelistview=app.root.ids.my_cw.my_listview)

输出

在此输入图像描述


这是一个显示输出的图片。

如果MyCustomWidgets的父级是BoxLayout怎么办?在我的实际代码中,ListView位于BoxLayout内部。那我该如何引用ListView呢?示例: class MyCustomWidgets(BoxLayout): pass - garlic
我已更新我的示例以反映MyCustomWidgets类是一个BoxLayout,而ListView是BoxLayout内的子小部件。有关引用ListView的详细信息,请参阅我的示例。 - ikolim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接