Kivy点击按钮动态向GridLayout添加控件无报错不生效如何解决?
问题原因及修复方案
你代码的核心问题有两个:
- 你在
newButt方法中写的middelWidget().add_widget(butt)是每次点击都新建了一个middelWidget类的实例,这个实例并没有被挂载到当前显示的界面树中,你向这个凭空创建的实例添加控件,界面自然不会有任何变化。 - 你没有将界面上实际渲染的
middelWidget实例暴露到可访问的上下文里,无法在App的方法中操作真实显示的网格布局。
修复步骤
1. 修改Python代码
- 在
rootWidget类中声明对应属性,用来绑定kv中实际的网格布局实例 - 在App的
build方法中保存根布局的引用,方便后续访问根布局下的子控件 - 修改
newButt方法,操作真实挂载在界面上的网格布局实例
from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.gridlayout import GridLayout from kivy.uix.button import Button class rootWidget(BoxLayout): middel_widget = None class topWidget(BoxLayout): print("top part") class middelWidget(GridLayout): pass class bottomWidget(BoxLayout): pass class NewButton(Button): pass class mainkv(App): def build(self): # 保存根布局实例引用 self.root_inst = rootWidget() return self.root_inst def newButt(self): print("button clicked") butt = NewButton(text="New Button") # 操作界面上真实存在的网格布局实例 self.root_inst.middel_widget.add_widget(butt) if __name__ == "__main__": mainkv().run()
2. 修改kv代码
- 给
rootWidget下的middelWidget实例添加id - 将id对应的实例绑定到
rootWidget提前声明的属性上
注意kv文件需要和App类名匹配,命名为mainkv.kv
<topWidget>: Button: text: 'Click add to grid' on_press: app.newButt() <middelWidget>: cols: 6 Button: text: 'middel Grid' <bottomWidget>: Button: text: 'bottom' <rootWidget>: orientation: 'vertical' # 将id为grid_id的网格实例绑定到root的middel_widget属性 middel_widget: grid_id Button: text: 'Root' topWidget: # 给实际渲染的网格实例分配id middelWidget: id: grid_id bottomWidget:
原理说明
Kivy中所有显示在界面上的控件都是挂载在界面树中的实例,只有操作这些已经被渲染的实例,修改才会反映到界面上。通过id绑定的方式可以快速在父控件中引用子控件实例,再通过根布局的引用传递,就能在App的逻辑方法中操作任意界面控件。
内容的提问来源于stack exchange,提问作者Human_Class
相关产品推荐
相关产品推荐

