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

Kivy设置面板开闭后按钮text属性值丢失但显示正常问题求助

Kivy默认设置面板引发的按钮text属性异常问题

问题描述

打开并关闭Kivy默认设置面板后,按钮的text属性值会被清空,但按钮显示的文本完全正常,这种属性与显示不一致的情况属于框架bug。

复现代码

from kivy.app import App
from kivy.uix.button import Button

class TestApp(App):
    def build(self):
        widget = Button(text='Hello World')
        widget.bind(on_release=self._button_callback)
        return widget

    def _button_callback(self, button):
        debug_string = f'{hex(id(button))}:{type(button.text)}:{button.text}'
        print(debug_string)

if __name__=='__main__':
    app = TestApp()
    app.run()

测试流程与结果

  1. 运行程序后,点击按钮输出:
    0x172aba17ed0:<class 'str'>:Hello World
    
  2. 按F1打开默认设置面板,直接关闭后再次点击按钮,输出变为:
    0x172aba17ed0:<class 'str'>:
    

此时按钮显示仍为“Hello World”,但text属性已为空字符串。测试环境:Python 3.10.4(64位)、Kivy 2.1.0。

原因分析

这是Kivy 2.1.0的已知bug:默认设置面板关闭时,会错误触发控件属性的重置逻辑,仅清空了Python层面的text属性引用,但控件渲染用的纹理数据未被修改,导致显示正常但属性值异常。

解决方案

方案1:自定义按钮保护text属性

重写按钮的text属性逻辑,避免被意外清空:

from kivy.app import App
from kivy.uix.button import Button
from kivy.properties import StringProperty

class SafeButton(Button):
    text = StringProperty('')

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self._backup_text = self.text

    def on_text(self, instance, value):
        # 仅在有效输入时更新,保留初始文本备份
        if value:
            self._backup_text = value
        super().on_text(instance, self._backup_text)

class TestApp(App):
    def build(self):
        widget = SafeButton(text='Hello World')
        widget.bind(on_release=self._button_callback)
        return widget

    def _button_callback(self, button):
        debug_string = f'{hex(id(button))}:{type(button.text)}:{button.text}'
        print(debug_string)

if __name__=='__main__':
    app = TestApp()
    app.run()

方案2:禁用默认设置面板

在App类中添加use_kivy_settings = False,彻底避免触发异常逻辑:

class TestApp(App):
    use_kivy_settings = False

    def build(self):
        widget = Button(text='Hello World')
        widget.bind(on_release=self._button_callback)
        return widget

    def _button_callback(self, button):
        debug_string = f'{hex(id(button))}:{type(button.text)}:{button.text}'
        print(debug_string)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 05:00:54