如何在kivymd中使用底页更改屏幕?

时间:2020-09-14 10:30:20

标签: python kivy kivymd

我在kivymd中制作了一个简单的应用程序。但是我无法在kivymd内单击按钮时更改屏幕。一切正常。但是,当我单击按钮时,它也会弹出吐司,但屏幕没有变化。会有什么变化或更好的实现方式?

app.py

from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.lang import Builder
from main_screen_str import helper_string
from kivy.core.window import Window
from kivymd.toast import toast
from kivymd.uix.bottomsheet import MDGridBottomSheet

Window.size = (300, 500)


class MainScreen(Screen):
    pass


class SettingsScreen(Screen):
    pass


class AboutScreen(Screen):
    pass


class MainApp(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.sm = ScreenManager()
        self.sm.add_widget(MainScreen(name="main_screen"))
        self.sm.add_widget(SettingsScreen(name="settings_screen"))
        self.sm.add_widget(AboutScreen(name="about_screen"))

        self.main_str = Builder.load_string(helper_string)

    def build(self):
        screen = Screen()
        screen.add_widget(self.main_str)
        return screen

    def callback_for_menu_items(self, *args):
        if args[0] == 'Home':
            toast(args[0])
            self.sm.current = "main_screen"

        if args[0] == 'Settings':
            toast(args[0])
            self.sm.current = "settings_screen"

        if args[0] == 'About':
            toast(args[0])
            self.sm.current = "about_screen"

    def show_example_grid_bottom_sheet(self):
        self.bottom_sheet_menu = MDGridBottomSheet()

        data = {
            "Home": "home",
            "Settings": "settings",
            "About": "information-outline",
        }
        for item in data.items():
            self.bottom_sheet_menu.add_item(
                item[0],
                lambda x, y=item[0]: self.callback_for_menu_items(y),
                icon_src=item[1],
            )
        self.bottom_sheet_menu.open()


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

此构建器字符串用于创建屏幕。 有更好的解决方案吗?

构建器字符串

helper_string = """
ScreenManager:
    MainScreen:
    SettingsScreen:
    AboutScreen:

<MainScreen>:
    name: 'main_screen'

    MDIconButton:
        icon: "menu"
        theme_text_color: "Custom"
        text_color: 1,0,0,1
        on_press: app.show_example_grid_bottom_sheet()
  
<SettingsScreen>:
    name: 'settings_screen'
    
<AboutScreen>:
    name: 'about_screen'      
"""

1 个答案:

答案 0 :(得分:1)

__init__()的{​​{1}}方法中,您正在使用以下行构建App

self.sm

但是 self.sm = ScreenManager() self.sm.add_widget(MainScreen(name="main_screen")) self.sm.add_widget(SettingsScreen(name="settings_screen")) self.sm.add_widget(AboutScreen(name="about_screen")) 未被用作GUI的一部分。因此,您对self.sm所做的更改不会影响您的GUI。接下来的行:

self.sm

基本上与前几行完全相同。

然后在您的self.main_str = Builder.load_string(helper_string) 方法中,创建一个新的build()并将Screen作为该self.main_str的子代添加。

虽然您可以将Screen作为ScreenManager的子代,但在您发布的示例中似乎没有任何作用。

这是Screen的一部分的修改版本,我认为它将满足您的要求:

MainApp

上面的代码大大简化了class MainApp(MDApp): # def __init__(self, **kwargs): # super().__init__(**kwargs) # self.sm = ScreenManager() # self.sm.add_widget(MainScreen(name="main_screen")) # self.sm.add_widget(SettingsScreen(name="settings_screen")) # self.sm.add_widget(AboutScreen(name="about_screen")) # # self.main_str = Builder.load_string(helper_string) def build(self): self.sm = Builder.load_string(helper_string) return self.sm # screen = Screen() # screen.add_widget(self.main_str) # return screen 方法,消除了build()方法,现在__init__()实际上是GUI的一部分。

请注意,当加载具有根节点为self.sm的{​​{1}}字符串时,将创建并返回该根节点。 kv字符串中的行:

Builder.load_string()

将创建一个kv实例以及为其列出的三个子实例,因此您的ScreenManager: MainScreen: SettingsScreen: AboutScreen: 方法中的代码将其复制。