如何通过调用 Kivy Python 中的函数来设置小部件属性?

How do I set widget attributes by calling a function in Kivy Python?

假设我的 RootWidget 中有一个 ThemeManager 对象作为 class 属性,如下所示:

class RootWidget(Widget):
    theme = ThemeManager()

ThemeManager定义了一个returns十六进制颜色的函数。

class ThemeManager:    
    def get_color(self):
        return '#ffffffff'

假设我使用 kv 文件在 RootWidget 中创建了一个 Button。我如何才能从 kv 文件中调用 ThemeManager 函数?这是一个不起作用的例子:

import kivy
kivy.require('1.9.0')
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.lang import Builder


class ThemeManager:
    def get_color(self):
        return '#ffffffff'


class RootWidget(Widget):
    theme = ThemeManager()


my_kv = Builder.load_string("""
#: import get_color_from_hex kivy.utils.get_color_from_hex
RootWidget:
    Button:
        color: get_color_from_hex(app.root.theme.get_color())
        text: "Test"
""")


class TestApp(App):
    def build(self):
        return my_kv

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

既然你的问题已经回答了,这里稍微解释一下,其实很简单(我觉得)。

app.root 是 None 在您的 Button 尝试读取函数的位置。因为事物的顺序是(松散地):-

  1. 已创建 RootWidget
  2. 一旦它和它的所有 children 完成(init 完成),object 将传递到 build()[=26 中的行=]
  3. app.root 仅在调用 TestApp.run()
  4. 时设置

至于为什么3.会发生,app.py中的init方法将self.root初始化为None。然后可以通过 load_kv(加载与此应用同名的 kv)或 运行(大多数情况下发生的情况)来设置它。

因此您可以在 on_press 事件中调用 app.root(因为这些仅在应用程序完全创建时响应用户交互时发生),但不能在 one-off 小部件初始化中调用事件。

有趣的是,root 未在 app.py 中定义为 ObjectProperty,这意味着您无法像使用标题和图标那样绑定到其中的更改。不确定它是否会改变,所以这可能没有实际意义。