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

Kivy结合ScreenManager与SQLite切换屏幕时数据不自动更新问题

问题根因
  • 操作了错误的屏幕实例:MainApp.build()中手动创建的Next()实例是完全脱离ScreenManager管理栈的孤立对象,对这个实例调用刷新方法,不会影响kv文件中实际加载、界面上真正显示的Next屏幕,属于无效操作。
  • 未使用屏幕生命周期钩子:Kivy的Screen类自带on_enter事件,该事件会在屏幕每次被切换为当前显示页时自动触发,原有代码未绑定该事件,切屏时自然不会自动执行数据拉取逻辑。
  • 定时刷新逻辑无效:原有代码中Clock.schedule_interval绑定的reset_text()方法仅返回查询到的字符串,不会更新Label组件的text属性,且up()方法从未被主动调用,完全不生效。
  • KV绑定仅初始化执行一次:<Next>规则下Label写的text: root.out1()只会在屏幕第一次实例化时执行一次,后续数据库数据变化不会触发该表达式重新计算。
修复步骤

1. 调整test.py

删除冗余的孤立实例创建逻辑,给Next屏幕绑定on_enter事件实现进入即刷新:

from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
import db_test

# 数据库初始化仅需执行一次
db_test.sq_crea()


class Main(Screen):
    inp = ObjectProperty(None)
    attempt = 1

    def btn(self):
        self.attempt = self.attempt + 1
        inp_val = self.inp.text
        db_test.insert_data(inp_val)
        self.inp.text = f"Attempt {self.attempt}"


class Next(Screen):
    def on_enter(self, *args):
        # 每次进入当前屏幕自动触发数据刷新
        self.out1()

    def out1(self):
        db_data = self.reset_text()
        self.ids.out1.text = db_data

    def reset_text(self):
        return str(db_test.data_out())


class WindowManager(ScreenManager):
    pass


kv_root = Builder.load_file("kvtest.kv")


class MainApp(App):
    def build(self):
        return kv_root


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

2. 调整kvtest.kv

移除Label上仅初始化执行的冗余text绑定:

WindowManager:
    Main:
    Next:

<Label>
    font_size : 0.08*self.width
    color: 1,1,1,1
    size_hint: 0.3, 0.1

<Button>
    font_size : 0.08*self.width
    color: 1,1,1,1
    size_hint: 0.3, 0.1

<TextInput>
    font_size : 0.08*self.width
    color: 1,1,1,1
    size_hint: 0.3, 0.1

<Main>
    name: "main"
    inp : inp

    FloatLayout:
        cols:2
        Button:
            text: 'Add to database'
            pos_hint: {"x": 0.1, "bottom": 1}
            on_release:
                root.btn()
                app.root.current = "next"
                root.manager.transition.direction = "left"

        TextInput:
            id:inp
            pos_hint: {"x": 0.5, "bottom": 0.8}
            text: 'Attempt 1'

<Next>
    name: "next"
    FloatLayout:
        Button:
            text: "Back"
            pos_hint: {"x": 0.1, "bottom": 0.8}
            on_release:
                app.root.current = "main"
                root.manager.transition.direction = "right"

        Button:
            id: upd
            text: "Update"
            pos_hint: {"center_x": 0.7, "bottom": 0.8}
            on_release:
                root.out1()

        Label:
            id: out1
            pos_hint: {"x": 0.1, "center_y": 0.5}

3. db_test.py无需修改

原有数据库创建、插入、查询逻辑可正常运行。

效果说明

修复后点击Add按钮,数据写入SQLite完成后自动切换到Next屏幕时,会立刻触发on_enter事件拉取最新库数据更新到Label,无需手动点击Update按钮即可看到刚新增的条目。如果后续需要用Clock做定时刷新,注意调度的回调函数中必须主动更新对应组件的属性,不能仅返回值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:12:26