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

Kivy动态创建按钮实现点击自删除功能的开发问题

问题根因
  • Kivy的Property机制仅识别类层级定义的Property对象,存放在普通Python列表内的ObjectProperty不会被框架注册为可绑定属性,KV解析时无法识别对应引用,必然触发报错。
  • KV语法中同个属性不允许重复赋值,原代码循环拼接KV时重复写入Buttons: Buttons属于语法错误。
  • 完全不需要提前声明一堆ObjectProperty存按钮引用:KV内定义的控件id会自动归集到控件实例的self.ids字典中;更简单的是,按钮的on_release事件触发时,回调的第一个参数就是按钮自身实例,直接用这个实例就能完成删除操作,连索引映射都不需要做。
  • 原代码用StringProperty存放列表数据属于类型错误,列表类型数据需要用ListProperty定义才能被KV正确识别。
可直接运行的修正代码
import kivy
from Nils_Programm_verkürzt import lektionstextlesen
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ListProperty
from kivy.lang import Builder

# 仅读取一次外部文件,避免类定义、实例化阶段重复IO
Inputfile = 'Lektionstext15.txt'
ReturnTuple = lektionstextlesen(Inputfile)
Satzliste = ReturnTuple[0]
Worterliste = ReturnTuple[1]

# 基础布局KV
kv = """
<Testwidget>:
    canvas:
        Rectangle:
            pos: 0, self.center_y
            size: self.width, 10
        Rectangle:
            pos: self.pos
            size: self.size
            source: 'background.png'
"""
# 按钮模板,on_release直接传入按钮实例self,不需要绑定id做索引映射
button_tpl = """
    Button:
        text: root.Satzliste[{index}]
        center_x: root.width / 2
        top: root.top - 100 - {offset}
        font_size: 30
        size: self.texture_size
        on_release: root.delete_btn(self)
"""
# 循环拼接所有动态按钮的KV定义
for idx, _ in enumerate(Satzliste):
    kv += button_tpl.format(index=idx, offset=idx*50)

Builder.load_string(kv)

class Testwidget(Widget):
    # 列表类型数据用ListProperty声明,保证KV侧可正确读取
    Satzliste = ListProperty(Satzliste)
    Worterliste = ListProperty(Worterliste)

    def delete_btn(self, btn):
        # 直接移除传入的按钮实例即可,不需要额外查找引用
        self.remove_widget(btn)

class GuiApp(App):
    def build(self):
        return Testwidget()

if __name__ == '__main__':
    GuiApp().run()
补充说明
  • 如果后续需要批量操作所有动态生成的按钮,直接遍历self.children筛选Button类型实例即可,也可以在控件初始化方法里遍历self.ids把需要的引用存到普通Python列表,不需要为每个按钮单独声明ObjectProperty。
  • 如果需要通过id获取指定按钮,只需要在KV里给按钮设置id: btn_{index},后续直接通过self.ids[f"btn_{index}"]就能拿到对应实例,不需要提前在Python侧做任何声明。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 02:57:08