Составьте список кнопок, которые переключаются на разные экраны в kivy
У меня есть еще одна проблема в моем проекте с kivy. У меня есть 50 экранов, и я хочу сначала отобразить список кнопок, который ссылается на экраны, когда кнопка нажата, screenmanager должен переключиться на соответствующий экран. Вот мой код, но я не знаю, что мне делать!
Источник: https://gist.github.com/daryasary/3a2be816c1f35b748866
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.app import App
#from kivy.uix.popup import Popup
#from kivy.uix.label import Label
from kivy.core.audio import SoundLoader
Builder.load_string('''
<MenuPage>:
BoxLayout:
BoxLayout:
size_hint:(.1, None)
Button:
text: 'Credit'
#on_press:root.show_popup()
#ListView:
#size_hint: .8,.9
#adapter:
#sla.SimpleListAdapter(
#data=["Item #{0}".format(i) for i in range(100)],
#cls=button.Button
#selection_mode='single',
#allow_empty_selection=False)
ListView:
size_hint: .8, .97
item_strings: [str(index) for index in range(50)]
BoxLayout:
size_hint:(.1, None)
Button:
text: 'atlas'
<Page>:
BoxLayout:
BoxLayout:
size_hint:(.1, None)
Button:
text: 'MENU'
on_press: root.manager.current = 'menu'
BoxLayout:
orientation:'vertical'
Button:
text:'Title'
size_hint:(1, .2)
Image:
source: '/home/hosein/Pictures/1.png'
size_hint:(1, .8)
BoxLayout:
size_hint:(.1, None)
Button:
text: 'atlas'
''')
class MenuPage(Screen):
M = SoundLoader.load('/home/hosein/Music/Man.mp3')
def plays(self):
if MenuPage.M.state == 'stop':
MenuPage.M.play()
else:
MenuPage.M.stop()
class Page(Screen):
pass
sm = ScreenManager()
menu = MenuPage(name='menu')
sm.add_widget(menu)
for i in range(50):
name = Page(name=str(i))
sm.add_widget(name)
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
1 ответ:
Все 50 "страниц" идентичны, поэтому было бы более разумно заменить их все одной страницей, которая изменяет содержание изображения / звука в зависимости от выбранной кнопки меню. Он использует меньше ресурсов и будет легче отлаживаться и обслуживаться.
Ваши файлы ресурсов (например, 1.png) также было бы лучше организовать, либо сгруппировав их в фиксированном подкаталоге, либо сославшись на них в коде, используя косвенный механизм, предоставляемый библиотеками (link)
Относительно ваш вопрос; механизм listview позволяет использовать несколько различных подходов, но simpleadapter будет недостаточно. Есть много хороших примеров для списков, представленных в документации ListView (Ссылка)
Как минимум, вам понадобится listadapter, функция для ответа на нажатие кнопки и привязка функции к объектам кнопки. Вы можете сделать это, связав обработчик событий
listadapter.on_selection_change
, но я нахожу более правильным создать класс элемента button с определенным обработчиком, так что то, что я предоставляю ниже.from kivy.uix.screenmanager import ScreenManager, Screen from kivy.lang import Builder from kivy.app import App from kivy.core.audio import SoundLoader from kivy.uix.listview import ListItemButton from kivy.properties import ListProperty, NumericProperty Builder.load_string(''' #:import la kivy.adapters.listadapter #:import factory kivy.factory <MenuButton>: size_hint_y: None height: dp(24) on_release: app.on_menu_selection(self.index) <MenuPage>: BoxLayout: BoxLayout: size_hint:(.1, None) Button: text: 'Credit' #on_press:root.show_popup() ListView: size_hint: .8,.9 adapter: la.ListAdapter( data=app.data, cls=factory.Factory.MenuButton, selection_mode='single', allow_empty_selection=True, args_converter=root.args_converter) BoxLayout: size_hint:(.1, None) Button: text: 'atlas' <Page>: BoxLayout: BoxLayout: size_hint:(.1, None) Button: text: 'MENU' on_press: root.manager.current = 'menu' BoxLayout: orientation:'vertical' Button: text:'Title' size_hint:(1, .2) Image: source: '/home/hosein/Pictures/1.png' size_hint:(1, .8) BoxLayout: size_hint:(.1, None) Button: text: 'atlas' ''') class MenuButton(ListItemButton): index = NumericProperty(0) class MenuPage(Screen): M = SoundLoader.load('/home/hosein/Music/Man.mp3') def plays(self): if MenuPage.M.state == 'stop': MenuPage.M.play() else: MenuPage.M.stop() def args_converter(self, row_index, title): print ("{0}={1}".format(row_index, title)) return { 'index': row_index, 'text': title } class Page(Screen): pass class TestApp(App): data = ListProperty(["Item #{0}".format(i) for i in range(50)]) def build(self): sm = ScreenManager() menu = MenuPage(name='menu') sm.add_widget(menu) for i in range(50): name = Page(name=str(i)) sm.add_widget(name) return sm def on_menu_selection(self, index): self.root.current = str(index) if __name__ == '__main__': TestApp().run()