为啥我的屏幕管理器不接受 .kv 文件中的所有屏幕?

Posted

技术标签:

【中文标题】为啥我的屏幕管理器不接受 .kv 文件中的所有屏幕?【英文标题】:Why isn't my Screen Manager accepting all of the screens from my .kv file?为什么我的屏幕管理器不接受 .kv 文件中的所有屏幕? 【发布时间】:2021-01-10 07:22:24 【问题描述】:

我无法弄清楚为什么屏幕管理器没有占用我的两个屏幕,即使我对其进行了简化。

通过 atom 使用 Python 3.6.1 和 kivy 1.11.1。窗户机。

Disp.py

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

class OS(Screen):
    def __init__(s, **kwargs):
        super(OS, s).__init__(**kwargs)
        print('in OS class: ')
        print(s)
        print(s.manager)

class TS(Screen):
    def __init__(s, **kwargs):
        super(TS, s).__init__(**kwargs)
        print("In TS class: ")
        print(s)
        print(s.manager)

class SM(ScreenManager):
    def __init__(s, **kwargs):
        super(SM, s).__init__(**kwargs)
        s.add_widget(OS())
        s.add_widget(TS())
        print("in SM class: ")
        print(s)
        print(s.children)

class DispApp(App):
    def build(s):
        return SM()


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

和Disp.kv

<SM>:
    OS:
    TS:

<OS>:
    name: 'Open'

<TS>:
    name: 'Trials'

输出:

in OS class: 
<Screen name=''> 
None  
In TS class: 
<Screen name=''> 
None 
in OS class: 
<Screen name='Open'> 
None 
In TS class: 
<Screen name='Trials'> 
None 
in SM class: 
<__main__.SM object at 0x10F911F0> 
[<Screen name='Open'>]

答:一旦初始化,TS 和 OS 屏幕就会采用 .kv 文件中的名称,但它们没有管理器。

B:为什么屏幕管理器只有一个孩子?

C:我只想在 Open Screen(OS 类)上打开一个文件,然后当它打开时,让该文件在 Trials Screen(TS 类)上运行。我认为该项目现在已经完成,除非我似乎无法进入屏幕管理器来引用其他类。 (而且我真的应该能够仅根据我的一般知识来实现​​屏幕管理器)

【问题讨论】:

【参考方案1】:

有几个概念需要明确。首先从ScreenManager 类访问屏幕的问题。 ScreenManager 将始终将当前屏幕作为子屏幕。要从ScreenManager 类访问不同的屏幕,您可以使用screens 属性,它将屏幕类作为列表返回,然后您可以枚举它们以访问任何单独的屏幕。您还可以使用get_screen(&lt;name&gt;)ScreenManager 函数通过其名称访问特定屏幕。

第二个问题是从其类中访问屏幕的信息(如名称、经理等)。当您尝试在屏幕的__init__ 方法中访问这些信息时,请记住屏幕的初始化尚未完成。因此,您得到空白和无响应。如果您通过Clock 添加延迟,那么您将看到信息将正确返回。

这两个问题都在修改后的 Disp.py 文件中得到解决和演示。请运行,你可以理解上面解释的概念:

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

class OS(Screen):
    def __init__(s, **kwargs):
        super(OS, s).__init__(**kwargs)
        Clock.schedule_once(lambda dt: s.info())
        
    def info(s):
        print('in OS class: ')
        print(s)
        print(s.manager)        

class TS(Screen):
    def __init__(s, **kwargs):
        super(TS, s).__init__(**kwargs)
        Clock.schedule_once(lambda dt: s.info())        

    def info(s):
        print('in OS class: ')
        print(s)
        print(s.manager)        

class SM(ScreenManager):
    def __init__(s, **kwargs):
        super(SM, s).__init__(**kwargs)
        print("From SM class: ")
        print(s.screens)
        print(s.screens[0])
        print(s.screens[1])
        print(s.get_screen('Open'))
        print(s.get_screen('Trials'))

class DispApp(App):
    def build(s):
        return SM()


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

【讨论】:

这说明了一切!非常感谢您的澄清!我真的觉得我掌握了一些我不正确的想法。再次感谢。

以上是关于为啥我的屏幕管理器不接受 .kv 文件中的所有屏幕?的主要内容,如果未能解决你的问题,请参考以下文章

我可以从 Python 触发在 KV 文件中创建的屏幕吗?

python- .py 文件中的 Kivy 屏幕管理器

如何在 KivyMD 的 .kv 文件中使用 kivy 中的数据表?

在没有屏幕管理器类的情况下在 Python 中更改屏幕

在单独的 .kv (Kivy) 文件中定义的屏幕之间切换

SDK 管理器不显示较旧的 API