kivyでメニューバー作ってみた
こんな感じ
ソースコード
#! kivy 1.0.9 # example.kv <MenuList>: canvas.before: Color: rgba: 1, 0, 0, .5 Rectangle: pos: self.pos size: self.size <MenuImage>: source: 'menu.png' keep_ratio: True <MenuBar>: end: True canvas.before: Color: rgba: 1, 0, 0, .5 Rectangle: pos: self.pos size: self.size MenuImage: center: 50, root.center_y size: 32, 32 <RootWidget>: MenuBar: pos: root.pos[0], root.height-90 size: root.width, 90
from kivy.app import App from kivy.uix.widget import Widget from kivy.uix.image import Image from kivy.properties import BooleanProperty, ObjectProperty from kivy.logger import Logger from kivy.uix.label import Label from kivy.uix.gridlayout import GridLayout from kivy.uix.scrollview import ScrollView class TestLabel(Label): """ For Testing MenuList """ def __init__(self, **kwargs): super().__init__(**kwargs) def on_touch_down(self, touch): if self.collide_point(touch.x, touch.y): Logger.info(f'[{self.__class__.__name__}\t] {self.text} was touched.') return True return super().on_touch_down(touch) class MenuList(ScrollView): def __init__(self, **kwargs): super().__init__(**kwargs) self.layout = GridLayout(cols=1, spacing=20, size_hint_y=None) self.layout.bind(minimum_height=self.layout.setter('height')) self.do_scroll_x = False self.add_widget(self.layout) MenuList.test_add_widget(self) def add_widget(self, widget, index=0, canvas=None): if isinstance(widget, GridLayout) or not self.children: super().add_widget(widget) else: if hasattr(widget, 'text_size'): widget.bind(size=self.__class__._update_each_text_rect) self.layout.add_widget(widget, index=index, canvas=canvas) @staticmethod def _update_each_text_rect(instance, value): instance.text_size = value[0]-10, value[1] @staticmethod def test_add_widget(menu_list): for i in range(5): lbl = TestLabel(text=f'Menu {i}', size_hint_y=None, height=40) menu_list.add_widget(lbl) class MenuImage(Image): toggled = BooleanProperty(False) def on_touch_down(self, touch): Logger.debug(f'[{self.__class__.__name__}\t] touched') if self.collide_point(touch.x, touch.y): self.toggled = not self.toggled return True return super().on_touch_down(touch) def on_toggled(self, instance, value): Logger.info(f'[{self.__class__.__name__}\t] toggled to {value}.') if not hasattr(self.parent, 'toggled'): Logger.warning(f'[{self.__class__.__name__}\t] {self.parent.__class__.__name__}\ has no boolean attr toggled.') self.parent.toggled = value class MenuBar(Widget): toggled = BooleanProperty(False) menu_list = ObjectProperty(None) def __init__(self, **kwargs): super().__init__(**kwargs) self.menu_list = MenuList() self.bind(size=self._update_size, pos=self._update_size) def on_toggled(self, instance, value): Logger.info(f'[{self.__class__.__name__}\t] toggled to {value}.') if self.menu_list is not None: if value: self.add_widget(self.menu_list) self._update_size(self, self.size) else: self.remove_widget(self.menu_list) def _update_size(self, instance, size): self.menu_list.size = (280, self.parent.height-90) self.menu_list.pos = self.parent.pos class RootWidget(Widget): def __init__(self, **kwargs): super().__init__(**kwargs) class ExampleApp(App): def build(self): return RootWidget() if __name__ == '__main__': ExampleApp().run()
途中まで書いた下書きが消えたので、以上です。