简体   繁体   English

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

[英]How to reference objects in other screens using kivy screenmanager

I am trying to update a field that exists in another screen but am not succeeding. 我正在尝试更新另一个屏幕中存在的字段,但没有成功。 I would be very very pleased when someone could tell me what I am doing wrong here. 当有人可以告诉我我在做什么错时,我会感到非常高兴。

myscreenskv.py: 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: .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()

You are trying to access ids dictionary, that's nice, yet in a completely different instance, that's why this error: 您正在尝试访问ids字典,这很好,但是在完全不同的实例中,这就是此错误的原因:

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

You need to access the right instance, to be able to access its properties, which in your case you need to access the ScreenManager , to access its screens property (a list of instances), from which you can do the desired edits of for example text: 您需要访问正确的实例,才能访问其属性,在这种情况下,您需要访问ScreenManager ,以访问其screens属性(实例列表),例如,可以从中进行所需的编辑文本:

MainScreen.action1(): MainScreen.action1():

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

To understand why it works let's look at the widget tree: 要了解它为什么起作用,让我们看一下小部件树:

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

here the ids are a dictionary in MainScreen accessible from MainScreen().ids (an instance) and this is the output: 这里的idsMainScreen中的字典,可从MainScreen().ids (一个实例)访问,这是输出:

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

which means you can't really assign the root widget to its own dictionary - at least not this way + makes no sense anyway, because you can just call root , which gives you the instance of the root widget. 这意味着您不能真正将根窗口小部件分配给它自己的字典-至少不是这种方式+仍然毫无意义,因为您只能调用root ,它为您提供了根窗口小部件的实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM