You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合Kivy文件与Python循环填充嵌套空Widget?

问题解决:KivyMD启动时用Python循环填充空布局

你的代码里on_grid方法虽然定义了填充逻辑,但从来没有被调用过,这就是MDGridLayout始终为空的原因。下面是几种启动时填充布局的可靠方法:

方法1:在屏幕初始化时调用填充函数

直接在MyWidget的__init__方法里执行填充逻辑,注意必须先调用父类的初始化方法:

from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.label import MDLabel
from kivymd.uix.screen import MDScreen

KV="""
MyWidget:
    MDBoxLayout:
        orientation: 'vertical'

        MDLabel:
            text:"hello world !"
            halign: 'center'

        MDGridLayout:
            id: _grid
            col: 2
        
        MDLabel:
            text:"hello world !"
            halign: 'center'
"""

class MyWidget(MDScreen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)  # 必须先调用父类初始化
        self.fill_grid()  # 调用填充方法

    def fill_grid(self):
        for i in range(6):
            self.ids._grid.add_widget(MDLabel(text=str(i+1)))

class MainApp(MDApp):
    def build(self):
        return Builder.load_string(KV)

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

方法2:使用on_kv_post方法(推荐)

Kivy提供了on_kv_post回调,会在KV语言解析完成、所有widget的id都可用后触发,适合处理依赖KV布局的初始化逻辑:

from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.label import MDLabel
from kivymd.uix.screen import MDScreen

KV="""
MyWidget:
    MDBoxLayout:
        orientation: 'vertical'

        MDLabel:
            text:"hello world !"
            halign: 'center'

        MDGridLayout:
            id: _grid
            col: 2
        
        MDLabel:
            text:"hello world !"
            halign: 'center'
"""

class MyWidget(MDScreen):
    def on_kv_post(self, base_widget):
        super().on_kv_post(base_widget)
        for i in range(6):
            self.ids._grid.add_widget(MDLabel(text=str(i+1)))

class MainApp(MDApp):
    def build(self):
        return Builder.load_string(KV)

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

方法3:用ObjectProperty绑定布局(可选)

如果想通过属性直接引用布局,而不是用ids,可以这样写:

from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivymd.app import MDApp
from kivymd.uix.label import MDLabel
from kivymd.uix.screen import MDScreen

KV="""
MyWidget:
    MDBoxLayout:
        orientation: 'vertical'

        MDLabel:
            text:"hello world !"
            halign: 'center'

        MDGridLayout:
            id: _grid
            col: 2
            # 绑定到MyWidget的grid_layout属性
            widget: root.grid_layout
        
        MDLabel:
            text:"hello world !"
            halign: 'center'
"""

class MyWidget(MDScreen):
    grid_layout = ObjectProperty(None)

    def on_grid_layout(self, instance, value):
        # 当grid_layout属性被赋值时触发
        for i in range(6):
            value.add_widget(MDLabel(text=str(i+1)))

class MainApp(MDApp):
    def build(self):
        return Builder.load_string(KV)

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

以上三种方法都能在程序启动时自动填充MDGridLayout,其中方法2是Kivy官方推荐的处理KV初始化后逻辑的方式,兼容性最好。

内容的提问来源于stack exchange,提问作者Flob74

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 11:35:27