将 ScreeManager 与 Kivy- 按钮布局一起使用时的问题不再有效

Issue when using ScreeManager with Kivy- buttons layout no longer works

所以我在尝试使用屏幕管理器时遇到了问题。因为我必须创建我的屏幕 classes 现在是 (Screen) 而不是 (GridLayout) 才能完全使用屏幕管理器,例如,button/layout 管理无法在 [=23= 中控制】 了?它曾经在屏幕上布置 5 列和 3 行,总共 15 个按钮。现在它只显示一个大的(屏幕)而不是网格布局。

class LandingScreen(Screen):
def build(self):
    return presentation
def __init__(self, **kwargs):
    super(LandingScreen, self).__init__(**kwargs)
    self.cols = 5
    self.buttons = []  # add references to all buttons here

    # Loop to make 20 different buttons on screen
    for x in range(15):
        self.buttons.append(Button(text='button ' + str(x)))  # make a reference to the button before adding it in
        self.add_widget(self.buttons[x])
        self.buttons[x].background_normal = 'YOUTUBE.png'

此处的按钮和列设置用于使用此循环创建 3 行 5 个按钮,但由于我将 (Screen) 添加到 class 而不是 (GridLayout),所以不会。我宁愿不在 .kv 文件中创建所有按钮,因为我认为在 .py 中更容易管理并且对我来说更有意义。

这是我的 .kv 文件:

<GridLayout>:
    cols: 5
    height: 480
    width: 800
    spacing: 25, 20
    padding: 25,25

<MyScreenManager>:
    LandingScreen:
    InputScreen:

<InputScreen>:
    AnchorLayout:

<LandingScreen>:
    GridLayout:
        cols: 5
        height: 480
        width: 800
        spacing: 25, 20
        padding: 25,25

这显然是多余的,因为我试图弄清楚如何让所有 15 个按钮再次显示,而不仅仅是一个。

谢谢!

您想将按钮添加到 Screen 内的 GridLayout,而不是直接添加到 Screen。为此,请使用 id 来引用 GridLayout.

但是,您不能在 __init__ 方法中使用 id,因为在完全初始化相应的小部件之前,不会应用 kv 文件中定义的规则。 Ryan Pi在这个问题中正确提供了解决方案:

Why can't I access the Screen.ids?

另一方面,要稍后更改屏幕,您必须在您的屏幕中定义 name 属性。

您的代码应该是:

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


kv_text='''\

<MyScreenManager>:
    LandingScreen:
    InputScreen:

<InputScreen@Screen>:
    name: 'input_sc'
    AnchorLayout:
        id: anchor_1

<LandingScreen@Screen>:
    name: 'landing_sc'
    GridLayout:
        id: grid_1
        cols: 5
        height: 480
        width: 800
        spacing: 25, 20
        padding: 25,25
'''

class MyScreenManager(ScreenManager):
    pass


class LandingScreen(Screen):
    def __init__(self, **kwargs):
        super(LandingScreen, self).__init__(**kwargs)
        self.buttons = [] # add references to all buttons here
        Clock.schedule_once(self._finish_init)

    def _finish_init(self, dt):
        self.ids.grid_1.cols = 5

        # Loop to make 20 different buttons on screen
        for x in range(15):
            self.buttons.append(Button(text='button {}'.format(x)))
            self.ids.grid_1.add_widget(self.buttons[x])
            self.buttons[x].background_normal = 'YOUTUBE.png'

class MyKivyApp(App):
    def build(self):
        return MyScreenManager()

def main():
    Builder.load_string(kv_text)
    app = MyKivyApp()
    app.run()

if __name__ == '__main__':
    main()

如果你想使用 Properties 而不是 ids 方法(参见 documentation),你应该这样做:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.clock import Clock
from kivy.properties import ObjectProperty


kv_text='''\

<MyScreenManager>:
    LandingScreen:
    InputScreen:

<InputScreen@Screen>:
    name: 'input_sc'
    AnchorLayout:
        id: anchor_1

<LandingScreen@Screen>:
    name: 'landing_sc'
    grid_1: grid_1
    GridLayout:
        id: grid_1
        cols: 5
        height: 480
        width: 800
        spacing: 25, 20
        padding: 25,25
'''

class MyScreenManager(ScreenManager):
    pass


class LandingScreen(Screen):

    grid_1 = ObjectProperty(None)    #<<<< Propertie

    def __init__(self, **kwargs):
        super(LandingScreen, self).__init__(**kwargs)
        self.buttons = [] # add references to all buttons here
        Clock.schedule_once(self._finish_init)

    def _finish_init(self, dt):
        self.grid_1.cols = 5
        # Loop to make 20 different buttons on screen
        for x in range(15):
            self.buttons.append(Button(text='button{}'.format(x)))
            self.grid_1.add_widget(self.buttons[x])
            self.buttons[x].background_normal = 'star.png'

class MyKivyApp(App):
    def build(self):
        return MyScreenManager()

def main():
    Builder.load_string(kv_text)
    app = MyKivyApp()
    app.run()

if __name__ == '__main__':
    main()