Implementar un listbox

votos
0

Necesito implementar un cuadro de lista para un móvil. Los únicos controles relevantes son las teclas de flecha arriba y abajo. El cuadro de lista debe mostrar tantas filas de elementos de una lista como quepan en la pantalla (screen_rows), una fila debe resaltarse (sel_row) y la pantalla debe ajustarse si el usuario golpea la flecha hacia arriba cuando el primer elemento está resaltado o hacia abajo si el último elemento está resaltado (es decir, el último elemento debe mostrarse y resaltarse si el usuario golpea cuando se resalta el primer elemento). La flecha hacia arriba resalta el elemento anterior y la flecha hacia abajo resalta el siguiente elemento.

He reunido algo, pero me preocupa haberme perdido algo en las pruebas. Debe haber una forma estándar de hacerlo, dada la prevalencia de listboxes que hay.

def up_key(self):
    if self.sel_row > 0:
       self.sel_row -= 1

    elif self.top_item > 0:  # top_item is the index of the first list item 
        self.top_item -= 1

    elif self.top_item == 0:
        if self.n_lines >= self.screen_rows: # n_lines is the number of items in the list
            self.top_item = self.n_lines - self.screen_rows
            self.sel_row = min(self.screen_rows-1, self.n_lines-1)
        else:
            self.top_item = 0
            self.sel_row = self.n_lines-1


def down_key(self):
    if self.sel_row < self.screen_rows-1 and self.sel_row < self.n_lines-1:
        self.sel_row += 1

    elif self.sel_row == self.screen_rows-1:
        bottom_item = self.top_item + self.screen_rows
        if bottom_item == self.n_lines:
            self.top_item = 0
            self.sel_row = 0
        if bottom_item < self.n_lines:
            self.top_item += 1

    elif self.sel_row == self.n_lines-1:
        self.top_item = 0
        self.sel_row = 0

def set_pos(self, pos):  # display item with index pos
    if pos < 0:
        pos = 0
    elif pos >= self.n_lines:
        pos = self.n_lines - 1

    if pos < self.screen_rows:
        self.top_item = 0
        self.sel_row = pos
    else:
        self.sel_row = min(self.screen_rows, self.n_lines)//2 - 1
        self.top_item = pos - self.sel_row
        if self.top_item >= self.n_lines - self.screen_rows:
            self.top_item = self.n_lines - self.screen_rows - 1
            self.sel_row = pos - self.top_item - 1

EDITAR: después de cada función llamo a una función de redibujar pantalla, que vuelve a dibujar la pantalla con top_item en la parte superior y sel-row resaltado.

Agregué una etiqueta de pseudo-código, en caso de que alguien tenga una versión en algo que no sea Python.

Publicado el 20/10/2009 a las 14:24
fuente por usuario
En otros idiomas...                            


1 respuestas

votos
1

Pocos programas de Python implementan listboxes desde cero, normalmente solo se toman de kits de herramientas existentes. ¡Eso puede explicar por qué no hay un verdadero "estándar" de herramientas cruzadas! -)

Llegando a su código, me imagino que set_posestá destinado a ser llamado justo después de cualquiera up_keyo down_keyestán terminados (usted no hace esta del todo claro).

Mi principal preocupación sería la repetición y la asimetría entre sus dos _keyrutinas. Seguramente dado que sus especificaciones son muy similares para las teclas arriba y abajo, desea delegar en una sola función que toma un argumento de "incremento", ya sea +1 o -1. Esa función común podría primero hacer self.sel_row += increment, luego volver inmediatamente en el caso común donde sel_rowtodavía está bien, es decir if self.top_item <= self.sel_row < self.top_item + self.screen_rows; de lo contrario, trate los casos donde sel_rowha salido de la región mostrada actualmente, ajustándolo self.top_item, saliendo si eso no causa la necesidad de envolvente, o finalmente tratando con las cajas envolventes.

Me gustaría aplicar "flat es mejor que anidado" al usar repetitivamente constructos de la forma "haz un chance de estado requerido, si las cosas están ahora bien, regresa" en lugar de lógicamente más complejo "si hacer algo simple estará bien , luego haga lo más simple, si se necesita algo un poco más complicado pero no terrible, entonces haga algo complicado, sino, si estamos en un caso realmente complicado, solucionemos el problema realmente complicado ", este último está lejos. más propenso al error y más difícil de seguir en cualquier caso.

Respondida el 20/10/2009 a las 16:30
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more