combobox.py (2490B)
1 ''' 2 ComboBox 3 ======= 4 5 Based on Spinner 6 ''' 7 8 __all__ = ('ComboBox', 'ComboBoxOption') 9 10 from kivy.properties import ListProperty, ObjectProperty, BooleanProperty 11 from kivy.uix.button import Button 12 from kivy.uix.dropdown import DropDown 13 from kivy.lang import Builder 14 15 16 Builder.load_string(''' 17 <ComboBoxOption>: 18 size_hint_y: None 19 height: 44 20 21 <ComboBox>: 22 background_normal: 'atlas://data/images/defaulttheme/spinner' 23 background_down: 'atlas://data/images/defaulttheme/spinner_pressed' 24 on_key: 25 if self.items: x, y = zip(*self.items); self.text = y[x.index(args[1])] 26 ''') 27 28 29 class ComboBoxOption(Button): 30 pass 31 32 33 class ComboBox(Button): 34 items = ListProperty() 35 key = ObjectProperty() 36 37 option_cls = ObjectProperty(ComboBoxOption) 38 39 dropdown_cls = ObjectProperty(DropDown) 40 41 is_open = BooleanProperty(False) 42 43 def __init__(self, **kwargs): 44 self._dropdown = None 45 super(ComboBox, self).__init__(**kwargs) 46 self.items_dict = dict(self.items) 47 self.bind( 48 on_release=self._toggle_dropdown, 49 dropdown_cls=self._build_dropdown, 50 option_cls=self._build_dropdown, 51 items=self._update_dropdown, 52 key=self._update_text) 53 self._build_dropdown() 54 self._update_text() 55 56 def _update_text(self, *largs): 57 try: 58 self.text = self.items_dict[self.key] 59 except KeyError: 60 pass 61 62 def _build_dropdown(self, *largs): 63 if self._dropdown: 64 self._dropdown.unbind(on_select=self._on_dropdown_select) 65 self._dropdown.dismiss() 66 self._dropdown = None 67 self._dropdown = self.dropdown_cls() 68 self._dropdown.bind(on_select=self._on_dropdown_select) 69 self._update_dropdown() 70 71 def _update_dropdown(self, *largs): 72 dp = self._dropdown 73 cls = self.option_cls 74 dp.clear_widgets() 75 for key, value in self.items: 76 item = cls(text=value) 77 # extra attribute 78 item.key = key 79 item.bind(on_release=lambda option: dp.select(option.key)) 80 dp.add_widget(item) 81 82 def _toggle_dropdown(self, *largs): 83 self.is_open = not self.is_open 84 85 def _on_dropdown_select(self, instance, data, *largs): 86 self.key = data 87 self.is_open = False 88 89 def on_is_open(self, instance, value): 90 if value: 91 self._dropdown.open(self) 92 else: 93 self._dropdown.dismiss()