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

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()

调整说明

  1. 将btn2保存为MainLayout的实例属性,确保组件实例不会被垃圾回收,文本更新时引用始终有效。
  2. 用App.get_running_app()替代全局app变量,这是Kivy官方推荐的获取当前应用实例的方式,避免全局引用在设置界面关闭后出现异常。

修改后,打开关闭设置界面再点击btn2,按钮文本就能正常同步更新了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:25:17