我怎样才能从Python引用Kivy的Root Widget?

Tan*_*ang 12 python-2.7 kivy

在Kivy语言中,可以使用类似的东西来引用根小部件

<RootWidget>:
    BoxLayout:
        SomeButton:
            on_press: print root
Run Code Online (Sandbox Code Playgroud)

但尝试从Python访问root是不可能的

class SomeButton(Button):
    def __init__(self, **kwargs):
        super(SomeButton, self).__init__(**kwargs)
        self.text = "Button"
        self.font_size = 15
    def on_press(self, *args):
        print root
Run Code Online (Sandbox Code Playgroud)

并将导致

NameError: global name 'root' is not defined
Run Code Online (Sandbox Code Playgroud)

或者如果使用self.root,

AttributeError: 'SomeButton' object has no attribute 'root'
Run Code Online (Sandbox Code Playgroud)

Jim*_*ris 14

如果你想从App获得实际的根小部件,那么我在任何Widget类中使用以下内容...

from kivy.app import App
...
class myWidget(BoxLayout):
    app= App.get_running_app()
    app.root.whatever-you-want
Run Code Online (Sandbox Code Playgroud)


Tot*_*tem 5

在kv文件中,root始终引用具有尖括号的父级.因此,您可以在kv文件中引用多个根,具体取决于您在文件中的位置.

# Root here refers to the parent class in angle brackets
<SomeClass>:
    BoxLayout:
        Label:
            text: root.label_text

# and further down in the same kv file, this other
# class is also a root.. here root refers to
# this class
<SomeOtherClass/Widget/LayoutEtc>:
    BoxLayout:
        Label:
            text: root.label_text
Run Code Online (Sandbox Code Playgroud)

在python文件中,这些类可以表示如下:

class SomeClass:

    label_text = StringProperty("I'm a label")

    def __init__(**kwargs):
        super(SomeClass, self).__init__(**kwargs)
        b = BoxLayout()
        l = Label(text=self.label_text)
        b.add_widget(l)
        self.add_widget(b)
        # now we're set up like the first class in the above kv file
Run Code Online (Sandbox Code Playgroud)

现在看看上面并比较kv文件如何将文本分配给标签,以及如何在上面的python文件中完成.在kv它是root.label_text,但在上面,班级使用self.如,text=self.label_text.添加boxlayout时也会使用它self.add_widget(b).self是一种引用类的当前实例的方法.

这就是你基本上如何在kv文件中引用'root',但是在python文件中.

如果您不知道为什么self使用,那么我建议学习python中的类,因为这就是对它的解释所在.


Tan*_*ang 3

我的解决方法是在主 App 的方法中声明一个全局变量build(),类似于global root和 ,root = self.root因为当您在 App 类中时可以访问根小部件。您可以使用 做同样的事情app。

  • **很可能是一个坏主意。** 您现在持有对根 Kivy 小部件的模块范围强引用,从而防止该小部件以及整个 Kivy 应用程序在应用程序关闭时被干净地垃圾收集。简而言之,[只需访问“App.get_running_app().root”,而不是像当前的最佳答案一样](/sf/answers/3050337811/)。如果这太麻烦,请将其封装在一个动态的神奇属性中,间接隐藏 getter 调用。 (2认同)