lunes, 10 de noviembre de 2008

Lección No. 7

Hoy retomaremos la lección 6, la cual complementaremos con nuevos elementos que estudiaremos como las grillas, los estilos/comportamientos y mejoraremos el aspecto del menú.

Materiales para esta lección
No podemos hacer esta lección si no tenemos los materiales de la lección 6 ya trabajados, además de esto necesitaremos:

– 3 iconos de 16x16


Abramos entonces nuevamente la carpeta donde se encuentra el proyecto anterior en mi caso denominada leccion6.

Empecemos por hacer algunas cosas que olvide en la lección pasada como es el darle funcionalidad a la opción Terminar del menú principal.

– Doble clic en el form MyFrame
– Clic en la pestaña Menu

– Clic en la opción Terminar
– Clic en la Events
– Clic en Component Event (botón E)

En el evento EVT_MENU asignamos un nombre a la función, yo le he puesto full_salida.


– Clic en la ficha Python (si estaba seleccionada esta ficha, debes entonces dar clic en la ficha Design y luego nuevamente en la ficha Python con el fin de que actualice el código sino, no podrás encontrar la función que estamos creando).
– Buscamos la función que acabamos de crear (full_salida)
– Y escribimos:

def full_salida(self,event): #init function

#add your code here
self.Close()

return #end function


Ahora ya podemos salir del programa al hacer clic en el menú Terminar.


Qué tal si le mejoramos la apariencia al menú colocando unos cuanto iconos.

En la ficha Menu, seleccionamos el primer ítem del menú denominado mascotas, luego en la ficha Properties buscamos la opción Bitmap; doble clic en esta opción.

Nos debe mostrar la siguiente ventana:


Hacemos clic en el botón RES, el cual nos muestra otra ventana:


En esta ventana debemos elegir el tipo de archivo que vamos a utilizar (Bmp, Jpg, Png, etc) y luego, debajo de la palabra Type existe un botón identificado con tres puntos seguidos … debes hacer clic ahí y localizar el archivo.

Una vez lo tengas localizado tendrás algo parecido a esto:


Haces clic en el botón OK, que te regresa a la ventana anterior y donde también debemos hacer clic en el botón OK. Guardas los cambios y ejecutas el programa para comprobar que hay un icono en nuestro menú de mascotas.

Repetimos los mismos pasos para el menú Terminar, obviamente seleccionando la imagen adecuada para este ítem.

Entonces debemos tener algo similar a esto:


Me imagino que repasaste algo de la lección si no es así es hora de que lo hagas ya que necesitamos crear un ítem de menú entre la opción Mascotas y Terminar denominada Lista Mascotas con su respectivo icono.

El resultado debe ser algo parecido a esto:


Ahora vamos a crear un form para Lista Mascotas al cual denominaremos frm_listar.


Nos volcamos a la ficha Project, hacemos clic con el botón derecho del mouse sobre la carpeta Design el cual nos mostrará un menú flotante en el cual debemos señalar la opción ADD wxMDIChildframe que se encuentra dentro de Add File|frame|panel; pues lo que vamos a crear es un form con la propiedad MDIChild (hija del frame principal MyFrame)
.



Al seleccionar esta opción se debe mostrar el form en la ventana de diseño, cambiemos su aspecto y fuente, y en la propiedad Name la cambiamos por frm_listar nombre con el que debe ser también guardado.

No olvidemos también asignar el título, cambiar el tamaño, etc.


Una vez “organizado” este form vamos a la ficha Components y ubicamos los siguientes componentes guiándonos en la gráfica:


Vamos a cambiar la propiedad de los static text a static text de sólo lectura.

Clic en el primer statictext, luego doble clic en Style de la ficha Properties, nos aparecerá la siguiente ventana:


En esta ventana se adicionan o se cambian algunos “estilos” (yo prefiero llamarlos comportamientos) de controles, formularios, entre otros. Si detallas bien, hacia abajo se encuentra entre otras la opción wxTE_READONLY, seleccionala, clic en aceptar y luego en Ok (observa que se tiene comportamientos interesantes como el ENTER, TAB, PASSWORD que utilizaremos más adelante en otros tutoriales).

Repite lo anterior con los otros dos controles (es posible que no se te pida confirmación de cambio y que solo baste con hacer clic en el botón Ok).

Lo que acabamos de hacer es darle a los controles que actualmente tenemos en el form el “estilo”/comportamiento/propiedad adicional -como lo quieras llamar- de sólo lectura, no podremos cambiar nada de lo que allí se muestre, ni tampoco escribir en estos controles.

Ahora haremos que nuestro form se pueda activar al hacer clic en el menú Lista Mascotas o haciendo clic con la combinación de teclas.

Si no recuerdas como se hace te recomiendo que leas nuevamente la lección anterior (que si que eres desobediente!!), no olvides importarlo en la sección de los includes, allá, arriba del código.


Aprovechamos también y hacemos el código del botón cerrar.


Ahora nos concentraremos en la grilla; vamos a agregar un wxGrid (grilla) que se llenará con algunos de los datos que contiene la tabla mascotas.


En la pestaña Components localizamos una carpeta denominada List que contiene entre otros componentes el que necesitamos, el Grid.

Hacemos doble clic en éste y verificamos que nos aparezca un pequeño recuadro café en la parte superior izquierda de nuestro form.


Para ubicarlo en el lugar que deseamos debemos hacer clic en el control identificado por gr seguido de un número de la pestaña Project del form frm_listar. Una vez seleccionado en esta sección podremos ubicar nuestro grid en el espacio que hemos dejado entre los controles y el botón cerrar.

Le cambiamos su ancho y alto y en la propiedad Name de la ficha Properties cambiamos su nombre a por ejemplo grilla.

Esto es lo que debemos tener hasta el momento.


Cambiamos la propiedad visible a False, agregamos un nuevo botón al que denominaremos bt_listar.

Debemos tener algo parecido a esto:

Creamos la función para el botón bt_listar (una función denominada por ejemplo llenar_grilla) y allí digitamos:
def llenar_grilla(self,event): #init function

#add your code here

sql1 = c.execute('SELECT COUNT(id) FROM mascotas')

res1 = c.fetchall()

rex1 = int(c.rowcount)

sql2 = c.execute('SELECT id,nombres,familia FROM mascotas')
res2 = c.fetchall()
rexx = int(c.rowcount)


#Limpiamos la grilla

self.grilla.Show(True)

self.grilla.ClearGrid()

""" Definimos (filas,columnas),
mediante este for
y la consulta sql1, res1
calculamos el número
de filas
que vamos a utilizar
"""

y = 0
for a in res1:
self.grilla.CreateGrid(a[0],3)
y+=1

#Se le da nombre a los encabezados de las columnas
#y luego se define el tamaño inicial de las columnas

#aunque más abajo se define AutoSizeColumns

self.grilla.SetColLabelValue(0,'CODIGO')

self.grilla.SetColLabelValue(1,'MASCOTA')

self.grilla.SetColLabelValue(2,'FAMILIA')
#Se muestran los resultados de la consulta

x = 0

for i in res2:

self.grilla.SetCellValue(x,0,str(i[0]))

self.grilla.SetCellValue(x,1,str(i[1]))

self.grilla.SetCellValue(x,2,str(i[2]))

self.grilla.AutoSizeColumns(True)

x+=1 self.bt_listar.Enable(False)
#Para evitar llamar nuevamente la grilla

return #end function

Si ejecutamos el programa podemos obtener algo como esto:



O un listado más completo, todo depende de cuántos registros tengas en la base de datos.

Ahora vamos a crear una función que al hacer clic en una de las celdas capture los datos y los ubique en los static_text.


Hacemos clic en la grilla, luego nos vamos a la ficha Events y buscamos el evento EVT_GRID_CELL_LEFT_DCLICK (el 3 de arriba hacia abajo), le damos el nombre a la función (por ejemplo obtiene_datos) y digitamos lo siguiente:

def obtiene_datos(self,event): #init function

#add your code here

"""Se obtienen los datos de la fila seleccionada en la grilla,
esto puedes servir
para eliminar datos, actualizar, etc"""
pos1 = self.grilla.GetCellValue(self.grilla.GetGridCursorRow(),0) #codigo

pos2 = self.grilla.GetCellValue(self.grilla.GetGridCursorRow(),1) #nombre
pos3 = self.grilla.GetCellValue(self.grilla.GetGridCursorRow(),2) #familia
self.txt_codigo.SetLabel(str(pos1))

self.txt_nombre.SetLabel(str(pos2))
self.txt_familia.SetLabel(str(pos3))
return #end function

Ahora cuando tengas datos listados en la grilla y hagas doble clic en una de las celdas, su contenido se visualizará también en los static_text.

Bueno, creo que eso es todo por hoy. Personalmente me gustaría que alguien que tenga buena experiencia en el trabajo con grillas escribiera un pequeño tutorial donde enseñara a editar, actualizar, eliminar, entre otras cosas; lo aquí visto con la grilla es algo realmente básico.

3 comentarios:

Anónimo dijo...

Loco eres mi maestro en esto, justo ahora ando haciendo un minisistema para practicar wxpython y con tus lecciones me ayudan en mucho. Tambien las practico en modo CONSOLA.
Estube revisando mucho como hacer que el MDI principal salga FULL SCREEN, pero aun no logro eso, solo poniendole las medidas en 'size', si sabes como hacer que el MDI se autoajuste a la pantalla seria genial.
Esta 7 leccion es muy buena. Continua, talvez muy pronto sea tu competencia haciendo un blog tuto de python ^^ ... pero igual reconocere que aprendi mucho de tu blog. O si gustas tambien puedo ayudarte colgando aportes xD

Anónimo dijo...

Creo que lo mejor que se puede hacer es buscar ese help de ayuda para wxpython, donde llegan muchos ejemplos, facil que hay uno para grillas.

Juan José dijo...

Muy bueno el manual, te comento que realice una pequeña modificación, que para el uso que yo le daría a la grilla me párese más interesante.
Y es que después de iniciar la ventana llene la grilla. En todo caso envés de dejar un botón para llenarla, lo que aria es actualizarla.

def initAfter(self):
#add your code here

sql2 = c.execute('SELECT id,nombres,familia FROM mascotas')
res2 = c.fetchall()
rexx = int(c.rowcount)

#Limpiamos la grilla
self.grilla.Show(True)
self.grilla.ClearGrid()
""" Definimos (filas,columnas),
mediante y la consulta sql, rexx
calculamos el número de filas
que vamos a utilizar """

self.grilla.CreateGrid(rexx,3)

#Se le da nombre a los encabezados de las columnas
#y luego se define el tamaño inicial de las columnas
#aunque más abajo se define AutoSizeColumns
self.grilla.SetColLabelValue(0,'CODIGO')
self.grilla.SetColLabelValue(1,'MASCOTA')
self.grilla.SetColLabelValue(2,'FAMILIA')
#Se muestran los resultados de la consulta

x = 0
for i in res2:
self.grilla.SetCellValue(x,0,str(i[0]))
self.grilla.SetCellValue(x,1,str(i[1]))
self.grilla.SetCellValue(x,2,str(i[2]))
self.grilla.AutoSizeColumns(True)
x+=1

#Para evitar llamar nuevamente la grilla
return