如何在 kivymd 中使用 bottom sheet 更改屏幕?
How can I change screen using bottom sheet in kivymd?
我用kivymd做了一个简单的app。但是我无法通过单击 kivymd 中的按钮来更改屏幕。一切都很好。但是当我点击按钮时它也会弹出 toast 但屏幕没有改变。对此会有哪些改变或更好的实施?
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'
"""
在 App
的 __init__()
方法中,您正在使用以下行构建 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"))
但是 self.sm
未用作 GUI 的一部分。因此,您对 self.sm
的更改对您的 GUI 没有影响。接下来的行:
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__()
方法,现在self.sm
实际上是GUI的一部分
请注意,当您加载具有 Builder.load_string()
根节点的 kv
字符串时,将创建并返回该根节点。 kv
字符串中的行:
ScreenManager:
MainScreen:
SettingsScreen:
AboutScreen:
导致 ScreenManager
实例连同为其列出的三个子实例一起创建,因此 __init__()
方法中的代码复制了该实例。
我用kivymd做了一个简单的app。但是我无法通过单击 kivymd 中的按钮来更改屏幕。一切都很好。但是当我点击按钮时它也会弹出 toast 但屏幕没有改变。对此会有哪些改变或更好的实施?
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'
"""
在 App
的 __init__()
方法中,您正在使用以下行构建 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"))
但是 self.sm
未用作 GUI 的一部分。因此,您对 self.sm
的更改对您的 GUI 没有影响。接下来的行:
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__()
方法,现在self.sm
实际上是GUI的一部分
请注意,当您加载具有 Builder.load_string()
根节点的 kv
字符串时,将创建并返回该根节点。 kv
字符串中的行:
ScreenManager:
MainScreen:
SettingsScreen:
AboutScreen:
导致 ScreenManager
实例连同为其列出的三个子实例一起创建,因此 __init__()
方法中的代码复制了该实例。