我在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'
"""
答案 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:
方法中的代码将其复制。