Widget kivy spinner con selección múltiple

Estoy buscando un widget kivy (preferiblemente en el archivo python + kv) de tipo spinner (o algo parecido) donde puedo seleccionar varios elementos a través de una checkbox, por ejemplo. Los elementos seleccionados deben estar disponibles en una tupla (?).

En la imagen start.png encontrarás la situación inicial.

introduzca la descripción de la imagen aquí

En un formulario hay una etiqueta y un campo de entrada de texto. Al hacer clic en una lista con las opciones disponibles debería aparecer. Para esto estoy usando un widget Spinner. Ver imagen select.png

introduzca la descripción de la imagen aquí

De esta lista quiero seleccionar varios elementos. En el ejemplo al lado de ‘Nederlands’, he seleccionado ‘Inglés’.

Cuando haya terminado, el campo de entrada de texto debe mostrar los elementos seleccionados en una lista separada por comas. Ver imagen resultado.png

introduzca la descripción de la imagen aquí

He intentado esto con e ListView utilizando el modo de selección múltiple. Pero el ListView está enlazado en el área del campo de texto. He intentado poner el ListView en una ventana emergente. Pero esto no funciona bien por alguna u otra razón …

Cualquier sugerencia es altamente apreciada. Gracias por adelantado.

Kivy no tiene dicho widget de forma predeterminada, pero es bastante fácil crear uno personalizado usando Button + DropDown + ToggleButton.

from kivy.base import runTouchApp from kivy.lang import Builder from kivy.factory import Factory from kivy.properties import ListProperty, ObjectProperty from kivy.uix.dropdown import DropDown from kivy.uix.button import Button class MultiSelectSpinner(Button): """Widget allowing to select multiple text options.""" dropdown = ObjectProperty(None) """(internal) DropDown used with MultiSelectSpinner.""" values = ListProperty([]) """Values to choose from.""" selected_values = ListProperty([]) """List of values selected by the user.""" def __init__(self, **kwargs): self.bind(dropdown=self.update_dropdown) self.bind(values=self.update_dropdown) super(MultiSelectSpinner, self).__init__(**kwargs) self.bind(on_release=self.toggle_dropdown) def toggle_dropdown(self, *args): if self.dropdown.parent: self.dropdown.dismiss() else: self.dropdown.open(self) def update_dropdown(self, *args): if not self.dropdown: self.dropdown = DropDown() values = self.values if values: if self.dropdown.children: self.dropdown.clear_widgets() for value in values: b = Factory.MultiSelectOption(text=value) b.bind(state=self.select_value) self.dropdown.add_widget(b) def select_value(self, instance, value): if value == 'down': if instance.text not in self.selected_values: self.selected_values.append(instance.text) else: if instance.text in self.selected_values: self.selected_values.remove(instance.text) def on_selected_values(self, instance, value): if value: self.text = ', '.join(value) else: self.text = '' kv = ''' BoxLayout: orientation: 'vertical' BoxLayout: Label: text: 'Select city' MultiSelectSpinner: id: city values: 'Sydney', 'Moscow', 'Warsaw', 'New York', 'Tokio' BoxLayout: Label: text: 'Select your favorite food' MultiSelectSpinner: id: food values: 'Fish and chips', 'Hot-dog', 'Hamburger' Label: text: 'You selected {} cities and {} as your favourite food.'.format(city.text, food.text) : size_hint: 1, None height: '48dp' ''' runTouchApp(Builder.load_string(kv)) 

Obtengo la solución … Aquí está la ruta: en el archivo kv primero podemos mencionar el widget desplegable, en el menú desplegable mencionaremos las casillas de verificación y esta es la respuesta … Aquí está el código del archivo kv:

 DropDown: padding: 0, 0, 0, root.width * 0.4 id: dropdown on_select: btn.text = '{}'.format(args[1]) GridLayout: size_hint_y: None height: 44 cols: 2 row_default_height: '10dp' Label: id: person text: 'Person' text_size: self.size valign: 'middle' CheckBox: text: 'check me' on_active: root.on_checkbox_active(person.text, self.active) GridLayout: size_hint_y: None height: 44 cols: 2 row_default_height: '10dp' Label: id: vehicle text: 'Vehicle' text_size: self.size valign: 'middle' CheckBox: id: vecle text: 'check me' on_active: root.on_checkbox_active(vehicle.text, self.active) GridLayout: size_hint_y: None height: 44 cols: 2 row_default_height: '10dp' Label: id: aircraft text: 'Air_craft' text_size: self.size valign: 'middle' CheckBox: text: 'check me' on_active: root.on_checkbox_active(aircraft.text, self.active) 

El archivo .py:

 class My_class(BoxLayout): def on_checkbox_active(checkbox_ref, name, checkbox_value): if checkbox_value: print('', name, 'is active') else: print('', name, 'is inactive') pass