Pregunta

Estoy intentando aprender kivy:cómo manipular la vista de lista y sus elementos enlazados.Aquí hay una parte de mi código donde tengo un problema.

Editar:Cambié el código, o más bien lo agregué todo, en lugar de simplemente publicar una parte.

import re
import sys
import json
import requests
import datetime
from datetime import datetime
from random import randint

import time
#Kivy Imports
import  kivy
from kivy.app import App
from kivy.uix import label
from kivy.uix.image import Image
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button

from kivy.properties import StringProperty, ObjectProperty

from kivy.adapters.listadapter import ListAdapter
from kivy.uix.listview import ListView, ListItemButton
from kivy.lang import Builder
from kivy.adapters import dictadapter
from kivy.uix.modalview import ModalView
#Kivy version
kivy.require('1.7.0')
#MainLayout Class with the GridView
class MainLayout(GridLayout):

    def __init__(self, **kwargs):
        super(MainLayout, self).__init__(**kwargs)

        self.text_input = ObjectProperty()  #reference to the textinput from .kv
        self.apps_list =  ObjectProperty()
        self.logo100 = ObjectProperty()        

        self.domain = self.ids.text_input.text 
        self.apps_list = self.ids.apps_list 
        self.logo100 = self.ids.logo100


        self.apps_list.adapter.bind(on_selected_item=self.callback)

    def on_enter(self):
        apps = {'a', 'b', 'c', 'd', 'e' ,'f', 'g'}
        if apps != None :          
            list_adapter = ListAdapter(data = apps, 
                                       selection_mode = 'single',
                                       allow_empty_selection = True,
                                       cls = ListItemButton,
                                       sorted_keys=[])

        self.apps_list.adapter = list_adapter


    def callback(self, adapter):
        if len(self.adapter.selection) == 0:
            print "No selected item"
        else:
            print self.adapter.selection[0].text       


class WabApp(App):
    def build(self):
        return MainLayout()

if __name__ == '__main__':
    WabApp().run()

Para el archivo .kv que utilicé:

<MainLayout>:

    rows: 2
    orientation: 'horizontal'


    GridLayout:
        cols: 2
        orientation: 'vertical'
        row_force_default: True 
        row_default_height: 50

        Image:
            id: logo100
            source: 'logo100.png'
            size_hint: [.2, .1]
            texture: self.texture
            size: self.texture_size

        TextInput:
            id: text_input
            markup: True
            text: ''
            font_size: 32
            size_hint: [1.8, .1]
            multiline: False                    
            on_text_validate: root.on_enter()
            hint_text: 'test'
    ListView:
        id: apps_list
        allow_empty_selection: True

Cuando hago clic en un elemento de la lista, no sucede nada.

Tampoco sé si debería usar:

self.apps_list.adapter.bind(on_selected_item=self.callback)

o

self.apps_list.adapter.bind(on_selection_change=self.callback)

En realidad, ni el primero ni el segundo muestran una palabra en la consola.Alguna sugerencia ?

¿Fue útil?

Solución

Hay varias cosas que estás haciendo mal, pero tu principal error es el número 2 de la siguiente lista:

  1. Puedes usar on_selection change.Hasta donde yo sé no hay on_selected_item.

  2. Estás vinculando el evento antes de crear el objeto..La siguiente instrucción está en el en eso:

    self.apps_list.adapter.bind(on_selected_item=self.callback)
    

    pero debería estar en on_enter después de crear el nuevo ListAdapter.Podría ser la última línea del método.Vea los códigos a continuación.

    def on_enter(self):
        ...
        self.apps_list.adapter = list_adapter
        self.apps_list.adapter.bind(on_selection_change=self.callback)
    
  3. MainLayout No contiene ningún adaptador.en el metodo on_enter, Las referencias self.adapter debe cambiarse a adapter (el parámetro del método) o self.apps_list.adapter.

  4. La forma en que estás creando las referencias a domain, apps_list y logo100 es extraño.No sabía de la existencia del ids atributo en el Widget pero puedes usarlo directamente.Entonces, en lugar de:

    self.apps_list.adapter = list_adapter
    

    Puedes usar:

    self.ids.apps_list.adapter = list_adapter
    

    No es necesario sobrecargar el _en eso_ método en absoluto.

Si no deseas acceder a apps_lists a través de ids atributo, luego puede agregar atributos en el encabezado del idioma kivy:

<MainLayout>:
    text_input: text_input
    apps_list: apps_list
    logo100: logo100

    rows: 2

Aquí está el código Python final que incluye todos los cambios mencionados.Omití las importaciones.

# ... your imports
class MainLayout(GridLayout):

    def on_enter(self):
        apps = {'a', 'b', 'c', 'd', 'e' ,'f', 'g'}
        if apps != None :
            list_adapter = ListAdapter(data = apps, selection_mode = 'single',
            allow_empty_selection = True, cls = ListItemButton, sorted_keys=[])
        self.apps_list.adapter = list_adapter
        self.apps_list.adapter.bind(on_selection_change=self.callback)

    def callback(self, adapter):
        if len(adapter.selection) == 0:
            print "No selected item"
        else:
            print adapter.selection[0].text

class WabApp(App):
    def build(self):
        return MainLayout()

if __name__ == '__main__':
    WabApp().run()

Otros consejos

¿Su ejemplo de código está desordenado y muy incompleto?¿Podrías proporcionarnos una aplicación funcional sencilla que muestre tu problema?

Puedo dar un par de sugerencias para solucionar las cosas, una de las cuales causaría el comportamiento que ve:

1) lo haces self.apps_list = ObjectProperty() en el __init__ método.Esto está mal, no crea una propiedad de objeto con ningún comportamiento útil, simplemente crea un nuevo atributo de instancia de tu clase, ¡que incluso reemplazas en la siguiente línea!En su lugar, deberías crear propiedades a nivel de clase (es decir,el mismo nivel que los métodos de función).

2) Incluye código que se vincula a un adaptador on_selection_change evento, sino también código en on_enter que reemplaza el adaptador.Su ejemplo es demasiado incompleto para saber cómo o cuándo se llama a este último, pero si sucede antes de hacer clic en un elemento de la lista, su evento nunca podrá activarse porque el adaptador al que está vinculado ha sido reemplazado.Esto daría el comportamiento que ves.Para solucionarlo, no reemplace el adaptador ni vuelva a vincular la devolución de llamada al nuevo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top