#python #kivy #kivymd
#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:
В вашем __init__()
методе 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"))
Но self.sm
не используется как часть вашего графического интерфейса. Таким образом, ваши изменения в 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__()
метод и теперь self.sm
фактически является частью графического интерфейса.
Обратите внимание, что когда вы загружаете kv
строку, в которой есть корневой узел с Builder.load_string()
, этот корневой узел создается и возвращается. Строки в вашей kv
строке:
ScreenManager:
MainScreen:
SettingsScreen:
AboutScreen:
в результате создается ScreenManager
экземпляр вместе с тремя дочерними элементами, перечисленными для него, поэтому код в вашем __init__()
методе дублировал это.