使用带有Kivy按钮布局的ScreeManager时的问题不再有效

时间:2017-06-30 02:16:30

标签: python python-3.x user-interface kivy kivy-language

所以我在尝试使用屏幕管理器时遇到了问题。因为我现在必须创建我的屏幕类(Screen)而不是(GridLayout)才能使用screenmanager,例如,按钮/布局管理不能再在python中控制了吗?它曾用于布置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)添加到类而不是(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个按钮,而不仅仅是那个。

谢谢!

1 个答案:

答案 0 :(得分:1)

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

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

Why can't I access the Screen.ids?

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

您的代码应为:

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()