首页 > 解决方案 > 在 Kivy 中半动态更改 GridLayout 网格大小

问题描述

我想通过 TextInput 在一个 Screen 对象中设置 GridLayout 的网格大小,以便第二个 Screen 中的 GridLayout 遵循用户的说明。

理想情况下,类似:

class SecondScreen(Screen):
    pass

class MainScreen(Screen):            
    def grid_button(self):
       # set grid in SecondScreen ???

class MyApp(App):
    def build(self):
       # Create the screen manager
       sm = ScreenManager()
       sm.add_widget(MainScreen(name='set_grid'))
       sm.add_widget(SecondScreen(name='grid'))
       return sm


if __name__ == "__main__":
    MyApp().run()

我不喜欢使用 GridLayout,但本质上,我想设置一个用户可确定的网格。

标签: python-3.xuser-interfacekivykivy-language

解决方案


我只是自己回答这个问题,尽管我很欣赏其他人提供的更简单的解决方案。我觉得这是一个非常hacky的答案:

class SecondScreen(Screen):
    set_cols = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(SecondScreen, self).__init__(**kwargs)
        # you need the following line or you'll get an AttributeError 
        self.cols = self.set_cols


class MainScreen(Screen):            
    set_grid = ObjectProperty(None)
    set_cols = ObjectProperty(None)
    
    def __init__(self, **kwargs):
        super(MainScreen, self).__init__(**kwargs)

    def grid_button(self):
        # check if input is an integer
        if isinstance(int(self.set_grid.text), int):
           set_cols = int(self.set_grid.text)

           # the line below was the difficult one - 
           # you need to know the screen index in the list of screens:
           App.get_running_app().root.screens[1].ids.set_cols.cols = set_cols 

           # edit: just found that you can alternatively 
           # use get_screen(name_of_your_screen) like so:
           # App.get_running_app().root.get_screen('second').ids.set_cols.cols = set_cols


class MyApp(App):
    def build(self):
        # Create the screen manager
        sm = ScreenManager()
        sm.add_widget(MainScreen())
        sm.add_widget(SecondScreen())
        return sm


if __name__ == "__main__":
    MyApp().run()

这是任何有兴趣的人的 my.kv 文件:

<MainScreen>:
    name: 'menu'
    set_grid: set_grid

    GridLayout:
        cols: 1
        GridLayout:
            cols: 2
            TextInput:
                id: set_grid
                text: "3"
                multiline:False
        Button:
            text: "Set grid size"
            on_press:
                root.grid_button()
        Button:
            text: "Next page"
            on_press:
                root.manager.transition.direction = 'left'
                root.manager.current = 'turtle'
        Button:
            text: 'Quit'
            on_press:
                app.stop()

<SecondScreen>:
    name: 'second'
    set_cols: set_cols

    GridLayout:
        id: set_cols
        cols: 2
        Button:
            text: 'Back to menu'
            on_press:
                root.manager.transition.direction = 'right'
                root.manager.current = 'menu'
        Label:
            text:"Test text"

推荐阅读