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

Kivy框架下Button的on_press绑定函数仅首次执行生效问题

问题原因

你的刷新功能失效核心是两个逻辑错误:

  • 旧组件删除目标找错
    你写的删除逻辑是遍历self.children(即MainScreen的直接子组件)查找ScrollView移除,但实际你每次生成的新ScrollView都是添加到self.ids.grids(id为grids的GridLayout)内部,ScrollView根本不是MainScreen的直接子组件,这段删除代码从第一次运行就没生效过。
    第一次运行能正常显示,是因为初始状态下grids里只有顶部搜索栏,第一个ScrollView加进去刚好排在搜索栏下方可视区域内;第二次触发搜索时,旧的ScrollView没有被移除,你又往grids里叠加了新的ScrollView,受GridLayout布局规则和你写的固定尺寸影响,新ScrollView直接被挤出可视范围,看起来就像界面完全没更新。
  • ScrollView尺寸设置不合理
    你给ScrollView写的size = (Window.width, Window.height)是硬编码固定值,既没有绑定窗口尺寸变化事件,也没有适配父容器的实际可用高度,很容易出现组件超出布局边界、无法正常显示的问题。
修复方案

最小修改版

只需要调整Python端refresh函数的遍历目标,同时修正ScrollView的尺寸参数即可:

def refresh(self, tags):
    # 遍历grids布局的子组件,删除旧的ScrollView
    for c in list(self.ids.grids.children):
        if isinstance(c, ScrollView): 
            self.ids.grids.remove_widget(c)
    tags = tags.lower()
    docs = db.collection('objects').where('type', '==', tags).stream()
    layout = GridLayout(cols = 1, spacing = 5, size_hint_y = None)
    layout.bind(minimum_height = layout.setter('height'))
    for doc in docs:
        button = RoundedButton(text = doc.get('specificType'), size_hint_y = None, height = 100)
        layout.add_widget(button)
    # ScrollView尺寸改为自适应父容器剩余空间
    root = ScrollView(size_hint = (1, 1))
    root.add_widget(layout)
    self.ids.grids.add_widget(root)

更稳定的优化版

不需要每次刷新都重复创建、删除ScrollView,直接在kv里提前定义好ScrollView和内部按钮容器,刷新时只需要清空旧按钮、添加新按钮即可,性能更好也不容易出布局问题:
修改kv代码,在grids布局里提前写好固定的ScrollView结构:

<MainScreen>:
    canvas.before:
        Color:
            rgba: (245/255,245/255,245/255,245/255)
        Rectangle:
            pos: self.pos
            size: self.size
    GridLayout:
        cols:1
        spacing:5
        size_hint_y:1
        id: grids
        GridLayout:
            id: box
            cols:2
            size_hint_y: None
            height:30
            TextInput: 
                id: ti
                hint_text: 'Search'
                size_hint: 1, None
                height:30
                background_normal: ''
            Button:
                text: 'search'
                size_hint_x: 0.1
                height:30
                on_press: root.refresh(root.ids.ti.text)
        # 固定的滚动区域,不需要动态增删
        ScrollView:
            id: scroll_area
            size_hint: (1,1)
            GridLayout:
                id: btn_container
                cols: 1
                spacing: 5
                size_hint_y: None
                height: self.minimum_height

对应简化后的refresh函数:

def refresh(self, tags):
    # 清空旧按钮
    self.ids.btn_container.clear_widgets()
    tags = tags.lower()
    docs = db.collection('objects').where('type', '==', tags).stream()
    for doc in docs:
        button = RoundedButton(text = doc.get('specificType'), size_hint_y = None, height = 100)
        self.ids.btn_container.add_widget(button)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:36:25