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
相关产品推荐
相关产品推荐

