Kivy AttributeError:“超级"对象在 ScreenManager 中没有属性“__getattr__"

2022-01-15 00:00:00 python kivy

问题描述

我正在尝试将方法绑定到微调器的文本值.它需要在不迟于显示 TestScreen 时绑定.如果我不使用 ScreenManager,这将有效(例如,如果 TestApp.build 返回 TestScreen 而不是 TestScreenManager).当 TestApp.build 返回 TestScreenManager 时,当我在 TestScreen.__init__

I am attempting to bind a method to the text value of a spinner. It needs to be bound no later than when the TestScreen is displayed. This works if I don't use the ScreenManager, (eg if TestApp.build returns TestScreen instead of TestScreenManager). When TestApp.build returns TestScreenManager I get the following error when I reference self.ids in TestScreen.__init__

AttributeError: 'super' object has no attribute '__getattr__'

Test.py

from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.app import App


class TestScreen(Screen):
    def __init__(self, *args, **kwargs):
        super(TestScreen, self).__init__(*args, **kwargs)
        self.ids.test_spinner.bind(text=self.on_spinner_select)

    def on_spinner_select(self, instance, data, *largs):
        print("In on_spinner_select")

    def print_spinner_value(self):
        print(self.ids.test_spinner.text)


class TestScreenManager(ScreenManager):
    pass


class TestApp(App):
    def build(self):
        #return TestScreen()
        return TestScreenManager()


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

Test.kv

<TestScreen>:
    name: "World Screen"

    BoxLayout:
        orientation: 'vertical'

        Label:
            text: "Name"
            font_size: 30

        BoxLayout:
            Label:
                text: "Active Selection"
                size_hint_x: .5

            Spinner:
                id: test_spinner
                text: "Value1"
                values: ["Value1", "Value2"]

        Button:
            text: "Print spinner value"
            on_press: root.print_spinner_value()


<TestScreenManager>:
    TestScreen:

我尝试在 on_enter 方法中绑定该方法,但我得到了同样的错误.但是,如果我在 init 函数中注释掉 self.ids 语句,self.ids 在方法 print_spinner_value 中确实有效.

I have tried binding the method in the on_enter method but I get the same error. However, self.ids does work in the method print_spinner_value if I comment out the self.ids statement in the init function.

目前我可以通过每次按下微调器时绑定函数来找到解决方法.但这似乎不是解决问题的最佳方法

Currently I was able to find a work around by binding the function every time the spinner is pressed. But that doesn't seem like the best way to handle the problem

on_press: self.bind(text=root.on_spinner_select)

所以我的问题是:如何在使用 ScreenManager 时将方法绑定到加载的微调器?

So my question is: How do I bind a method to the spinner on load while using the ScreenManager?


解决方案

我猜你尝试绑定这个方法的时候你的屏幕初始化还没有完成.试试这个:

I guess the init of your screen hasn't finished when you try to bind this method. Try this:

...
from kivy.clock import Clock
...
class TestScreen(Screen):
    def __init__(self, **kwargs):
        super(TestScreen, self).__init__(**kwargs)
        Clock.schedule_once(self.on_start)

    def on_start(self, *args):
        self.ids.test_spinner.bind(text=self.on_spinner_select)

相关文章