如何使用kivy screenmanager引用其他屏幕中的对象

How to reference objects in other screens using kivy screenmanager

我正在尝试更新存在于另一个屏幕中但未成功的字段。 如果有人能告诉我我在这里做错了什么,我会非常非常高兴。

myscreenskv.py:

style = r'''
# File: myscreenskv.py
#: import myscreens myscreens

<ScreenManagement>:
    MainScreen:
    Screen1:
    Screen2:

<MainScreen>:
    name: 'main'
    mainlog:mainlog
    id: scrmain
    BoxLayout:
        orientation: "vertical"
        Label:
            text: "Main"
        Label:
            id: mainlog
        Button:
            text: "go to screen 1"
            on_press:
                app.root.current = "screen1"
                root.action1()
        Button:
            text: "go to screen 2"
            on_press:
                app.root.current = "screen2"
                root.action2()

<Screen1>:
    name: 'screen1'
    sc1log:sc1log
    id: scr1
    BoxLayout:
        orientation: "vertical"
        Label:
            text: "Screen1"
        Label:
            id: sc1log
        Button:
            text: "go to main screen"
            on_press: app.root.current = "main"
        Button:
            text: "go to screen 2"
            on_press: app.root.current = "screen2"

<Screen2>:
    name: 'screen2'
    id: scr2
    sc2log:sc2log
    BoxLayout:
        orientation: "vertical"
        Label:
            text: "Screen2"
        Label:
            id: sc2log
        Button:
            text: "go to main screen"
            on_press: app.root.current = "main"
        Button:
            text: "go to screen 1"
            on_press: app.root.current = "screen1"

'''

.py:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from myscreenskv import style

class MainScreen(Screen):
    def __init__(self, **kwargs):
        super(MainScreen, self).__init__(**kwargs)

    def action1(self):
        self.ids.scr1.sc1log.text = 'Coming from main'

    def action2(self):
        self.ids.scr2.sc2log.text = 'Coming from main'

class Screen1(Screen):
    def __init__(self, **kwargs):
        super(Screen1, self).__init__(**kwargs)

    def action1(self):
        self.ids.main.mainlog.text = 'Coming from screen1'

    def action2(self):
        self.ids.scr2.sc2log.text = 'Coming from screen1'


class Screen2(Screen):
    def __init__(self, **kwargs):
        super(Screen2, self).__init__(**kwargs)

    def action1(self):
        self.ids.main.mainlog.text = 'Coming from screen2'

    def action2(self):
        self.ids.scr1.sc1log.text = 'Coming from screen2'

class MyscreensApp(App):
    def build(self):
        Builder.load_string(style)
        sm = ScreenManager()
        sm.add_widget(MainScreen())
        sm.add_widget(Screen1())
        sm.add_widget(Screen2())
        sm.current = 'main'
        return sm


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

您正在尝试访问 ids 字典,很好,但在完全不同的实例中,这就是为什么出现此错误:

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

您需要访问正确的实例,才能访问其属性,在您的情况下,您需要访问 ScreenManager,才能访问其 screens 属性(实例列表),您可以从中对例如文本进行所需的编辑:

MainScreen.action1():

self.manager.screens[1].sc1log.text = 'Coming from main'
# no ids, because you put it into a variable before

要了解其工作原理,让我们看一下小部件树:

<MainScreen>:
    id: scrmain
    BoxLayout:
        Label:
        Label:
            id: mainlog
        Button:
        Button:

此处 idsMainScreen 中的字典,可从 MainScreen().ids(实例)访问,这是输出:

{'mainlog': <WeakProxy to <kivy.uix.label.Label object at 0x12345678>>}

这意味着您不能真正将根小部件分配给它自己的字典 - 至少不是这样 + 无论如何都没有意义,因为您可以调用 root,它为您提供了根小部件。