Kivy 2.1.0应用关闭设置后UI文本更新失效问题求助
问题描述
启动应用后点击btn2,按钮文本会按预期变化;但通过btn1打开设置界面并关闭后,再次点击btn2,虽能触发回调(打印对应信息)、计数器也正常递增,但按钮文本变为空值且无法同步更新到UI。经测试其他标签组件也存在该问题。使用的Kivy版本为2.1.0。
相关代码
from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button class MainLayout(BoxLayout): def __init__(self, **kwargs): super().__init__(**kwargs) btn1 = Button(text="Settings", size_hint=(.5, 1), on_press=self.btn1_on_press) btn2 = Button(text="0", size_hint=(.5, 1), on_press=self.btn2_on_press) self.add_widget(btn1) self.add_widget(btn2) self.counter = 0 def btn1_on_press(self, btn): app.open_settings() def btn2_on_press(self, btn): print("btn pressed: ", btn) self.counter += 1 btn.text = str(self.counter) class MyApp(App): def build(self): self.use_kivy_settings = False return MainLayout() def build_config(self, config): config.setdefaults("settings", { "dark_mode": True, }) def build_settings(self, settings): settings.add_json_panel("settings", self.config, data="""[ { "type": "bool", "title": "Dark mode", "desc": "Enable dark mode", "section": "settings", "key": "dark_mode" } ]""") if __name__ == '__main__': app = MyApp() app.run()
环境依赖
$ pip freeze | grep -i kivy Kivy==2.1.0 Kivy-Garden==0.1.5
解决方案
问题源于全局变量app的引用不规范,以及组件实例未被布局类持有导致的引用丢失。调整代码如下:
from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button class MainLayout(BoxLayout): def __init__(self, **kwargs): super().__init__(**kwargs) btn1 = Button(text="Settings", size_hint=(.5, 1), on_press=self.btn1_on_press) # 将btn2保存为实例属性,避免被垃圾回收 self.btn2 = Button(text="0", size_hint=(.5, 1), on_press=self.btn2_on_press) self.add_widget(btn1) self.add_widget(self.btn2) self.counter = 0 def btn1_on_press(self, btn): # 使用官方推荐的方式获取当前应用实例 App.get_running_app().open_settings() def btn2_on_press(self, btn): print("btn pressed: ", btn) self.counter += 1 # 通过实例属性更新文本,确保引用有效 self.btn2.text = str(self.counter) class MyApp(App): def build(self): self.use_kivy_settings = False return MainLayout() def build_config(self, config): config.setdefaults("settings", { "dark_mode": True, }) def build_settings(self, settings): settings.add_json_panel("settings", self.config, data="""[ { "type": "bool", "title": "Dark mode", "desc": "Enable dark mode", "section": "settings", "key": "dark_mode" } ]""") if __name__ == '__main__': app = MyApp() app.run()
调整说明
- 将
btn2保存为MainLayout的实例属性,确保组件实例不会被垃圾回收,文本更新时引用始终有效。 - 用
App.get_running_app()替代全局app变量,这是Kivy官方推荐的获取当前应用实例的方式,避免全局引用在设置界面关闭后出现异常。
修改后,打开关闭设置界面再点击btn2,按钮文本就能正常同步更新了。
内容的提问来源于stack exchange,提问作者alex10791
相关产品推荐
相关产品推荐

