Kivy:GetParentInsideWidget是在python中添加的

Kivy:GetParentInsideWidget是在python中添加的,python,kivy,Python,Kivy,如何在不是由kvlang添加而是在python中添加的小部件中获取对父级的引用。 通常,您只需调用self.parent,但是如果在python中将小部件添加到父级,则返回Null 例如: import kivy kivy.require('1.9.0') # replace with your current kivy version ! from kivy.app import App from kivy.lang import Builder from kivy.uix.screenma

如何在不是由kvlang添加而是在python中添加的小部件中获取对父级的引用。 通常,您只需调用
self.parent
,但是如果在python中将小部件添加到父级,则返回
Null

例如:

import kivy
kivy.require('1.9.0') # replace with your current kivy version !

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.clock import Clock

kvlang = '''
<ScreenManagement>:
    ScreenOne:

<ScreenOne>:
    name: 'First'


<ScreenTwo>:
    name: 'Second'

'''


class ScreenManagement(ScreenManager):
    def __init__(self,**kwargs):
        super().__init__(**kwargs)

        def setup(*args):
            self.add_widget(ScreenTwo())    #add ScreenTwo later in python

        Clock.schedule_once(setup)

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

        def setup(*args):
            print("Parent of ScreenOne: {}".format(self.parent))        #this is working
        Clock.schedule_once(setup)

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

        def setup(*args):
            print("Parent of ScreenTwo: {}".format(self.parent))        #this is not working, self.parent will return None
        Clock.schedule_once(setup)



class MyApp(App):

    def build(self):
        Builder.load_string(kvlang)
        return ScreenManagement()


if __name__ == '__main__':
    MyApp().run()
导入kivy
kivy.require('1.9.0')#替换为当前的kivy版本!
从kivy.app导入应用程序
从kivy.lang导入生成器
从kivy.uix.screenmanager导入screenmanager,屏幕
从kivy.clock导入时钟
kvlang=''
:
第一屏:
:
名字:“第一”
:
姓名:“第二”
'''
类屏幕管理(屏幕管理器):
定义初始(自我,**kwargs):
超级()
def设置(*参数):
self.add_小部件(ScreenTwo())#稍后在python中添加ScreenTwo
时钟。安排一次(设置)
一级屏幕(屏幕):
定义初始(自我,**kwargs):
super()。\uuuu init\uuuuu()
def设置(*参数):
打印(“ScreenOne的父项:{}.format(self.Parent))#这正在工作
时钟。安排一次(设置)
第二类屏幕(屏幕):
定义初始(自我,**kwargs):
super()。\uuuu init\uuuuu()
def设置(*参数):
打印(“ScreenTwo的父项:{}.format(self.Parent))#这不起作用,self.Parent将返回None
时钟。安排一次(设置)
类别MyApp(应用程序):
def生成(自):
Builder.load_字符串(kvlang)
返回屏幕管理()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
MyApp().run()
这将返回:

Parent of ScreenOne: <__main__.ScreenManagement object at 0x7f98a3fddb40>
Parent of ScreenTwo: None
ScreenOne的父项:
ScreenTwo的父项:无

添加的小部件实际上有一个对其父部件的有效引用:

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

from kivy.lang import Builder
Builder.load_string('''
<ScreenTwo>
    Label:
        text: 'Hello, world'    
''')

class ScreenManagement(ScreenManager):
    def __init__(self,**kwargs):
        super(ScreenManagement, self).__init__(**kwargs)
        screen = ScreenTwo()

        print(screen.parent)
        self.add_widget(screen)  
        print(screen.parent)


class ScreenTwo(Screen):
    def on_touch_down(self, *args):
        print(self.parent)


class MyApp(App):
    def build(self):
        return ScreenManagement()


if __name__ == '__main__':
    MyApp().run()
从kivy.app导入应用
从kivy.uix.screenmanager导入screenmanager,屏幕
从kivy.lang导入生成器
Builder.load_字符串(“”)
标签:
文字:“你好,世界”
''')
类屏幕管理(屏幕管理器):
定义初始(自我,**kwargs):
超级(屏幕管理,自我)。\uuuuu初始化(**kwargs)
screen=ScreenTwo()
打印(screen.parent)
self.add_小部件(屏幕)
打印(screen.parent)
第二类屏幕(屏幕):
def on_触控向下(自身,*参数):
打印(self.parent)
类别MyApp(应用程序):
def生成(自):
返回屏幕管理()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
MyApp().run()

在他们的
\uuuu init\uuuu
方法中,它不可用。

您想用它实现什么?也许更多一点的上下文会有帮助。我想从父类访问变量,当然我也可以在子类的实例化中将它们作为参数传递,但我想知道为什么这不可能我正在尝试做的。嗯,你有什么线索为什么不可以?我能想到的解决方法似乎有点笨拙:
parent=sys.\u getframe().f_back.f_locals['self']
@Sebastian
parent
属性在创建小部件时没有实例化,因为无法判断您将要做什么,或者它是否有任何父属性。只有将此小部件添加到某个层次结构后,才能将其设置为合理的值。无论如何,如果您只想使用父变量在小部件中进行一些初始化,那么您可以在父(self、screen、parent)上定义
方法并将代码移到那里。一旦此属性变为有效,并且您可以使用
parent
参数访问父级,就会调用此属性。