martes, 16 de agosto de 2011

Apuntes: Patrón Singleton en Tkinter.

Esta vez pretendo dejarles una pequeña solución (algo rebuscada), para implementar el patrón de diseño singleton a las ventanas que creamos en Tkinter.

Para más información acerca del patrón de diseño singleton. Click aquí -> Wikipedia

# Código de mi solución.

from Tkinter import *
class ventana( Toplevel ):
    _instance = None
    def __init__(self):
        if ventana._instance is None:
            ventana._instance = ventana
            Toplevel.__init__(self)
            self.protocol("WM_DELETE_WINDOW", self.initSingleton)
            # más código para inicializar al objeto ventana.

    def initSingleton(self):
        self.destroy()
        ventana._instance = None

# fin de la clase ventana.

def callback():
    a = ventana()

master = Tk()
fr  = Frame(master)
bt = Button(fr, text="Presioname", command=callback)
bt.pack()
fr.pack()
master.mainloop()
           

Tkinter también es compatible con un mecanismo llamado controladores de protocolo. Aquí, el término protocolo se refiere a la interacción entre la aplicación y el gestor de ventanas. El protocolo más utilizado es el llamado WM_DELETE_WINDOW, y se utiliza para definir lo que sucede cuando el usuario cierra explícitamente una ventana con el gestor de ventanas.

widget.protocol ("WM_DELETE_WINDOW", handler)

En nuestro ejemplo de Singleton, al presionar la cruz de nuestra ventana ésta se destruye y el atributo _instance de la clase ventana se pone nuevamente a None.
Espero que se entienda y que les sea útil.

martes, 9 de agosto de 2011

Apuntes: Patrón MVC.

M: Modelo.
V: Vista.
C: Controlador.

Modelo: Datos y reglas de negocio.
Vista: Interfaces gráficas. (Plantillas las cuales son encargadas de mostrar la información almacenada en el Modelo)
Controlador: Gestiona las entradas del usuario, transporta peticiones al modelo y regresa a la vista las respuestas que el modelo le hace. (Un tramitel, cadete de mensajería. Así lo veo Ôò)

Voy hacer una analogía con una ferretería. (Espero que se entienda, y no confunda a nadie; al menos así lo interpreté yo)

ActoresHistoria = {'Cliente' : 'Usuario' ;
                              'Empleado' : 'Controlador' ;
                              'Depósito' : 'Modelo';
                              'Comunicación (Mensaje)' : 'Vista'}

class sistemaFerreteria:

El clinte llega a la ferretería a comprar unos tornillos para un trabajo que está realizando, al entrar al negocio ve al empleado sentado detrás del mostrador. Se acerca a él y de antemano se da cuenta que la única forma conocida para solicitar lo que está buscando se hace através de la comunicación. Entonces inicia la comunicación:

- Evento de Entradas -
Cliente: ¡Hola, buenos días!
Empleado: ¡Buenos días Joven! ( Imaginen al cliente un tipo imberbe, de unos 25 años )
Cliente: Estoy buscando 12 tornillos con estás medidas. ( El joven cliente le da las medidas )
Empleado: Aguardeme un segundo, voy a consultar al depósito si nos queda esa cantidad y ese tipo de tornillos.

- Petición -
El empleado se diríge al depósito y le pide a Pepe Lui - quien trabaja en ese área -  que le busque y entregue los tornillos que el cliente le ha solicitado. Pepe Lui siempre predispuesto inicia la búsqueda. Al encontrar los tornillos, Pepe Lui hace entrega de los mismos al empleado del mostrador. (Por cierto, al empleado del mostrador lo llaman Papa Chino).

- Actualización -
Papa Chino -( el empleado del mostrador Ôo`)- le lleva al cliente lo que él le solicitó.

- Evento Salida-
El cliente recibe los tornillos y contento se dirige a terminar su trabajo.

- Fin - óÒ

# Notas:
- El modelo puede tener varias vista, cada una con su correspondiente controlador -
Imaginemos que la ferretería es demasiado grande, y que dentro del depósito hay diferentes sectores y diferentes empleados para cada sector.
También imaginemos que hay más de un empleado en el mostrador.

- Responasibilidad de los elementos del patrón. -

El modelo es responsable de:
* Acceder a la capa de almacenamiento de datos.
* Definir las reglas de negocio.

El controlador es responsable de:
* Recibir los eventos de entrada (Click, un cambio en el campo de texto, etc...)
* Contener reglas de gestión de eventos. Por ejemplo:  Si se produce el evento "X", entonces realizar la acción "W". Estás acciones pueden suponer una petición al modelo o una actualización a las vistas. Cómo así también mostrar un mensaje de error, etc...

Las vistas son responsables de:
* Recibir datos del modelo y mostrarlo al usuario.
* Tener un registro de su controlador asociado.



¬ô debianitram

lunes, 8 de agosto de 2011

ttk.Notebook

Aquí vengo con una pequeña solución para Notebook del módulo ttk.

vruno.interfazRegistroUno -> Tkinter.Frame()
vrdos.interfazRegistroDos -> Tkinter.Frame()
interfazRegistroUno & interfazRegistroDos son clases que heredan de Frame.

# Código.
from Tkinter import *
import ttk
import vruno
import vrdos

master = Tk()
nt = ttk.Notebook(master)
frame1 = Frame(nt)
frame2 = Frame(nt)
nt.add(frame1, text="Registro Uno")
nt.add(frame2, text="Registro Dos")
nt.pack()
registroUno = vruno.interfazRegistroUno(frame1)
registroDos = vrdos.interfazRegistroDos(frame2)


Ejemplo del código interfazRegistroUno:

From Tkinter import *
class interfazRegistroUno(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self._config()
        self.initUI()
        # ... más código...
    def initUI(self):
        # Aquí se crean los widget: Label, Entry, OptionMenu, etc...
    def _config(self):
        # Aquí se configuran los widget. ;)

martes, 2 de agosto de 2011

Sqlite (Apuntes)

Vagamente desde Wikipedia : SQLite es un sistema de gestión de bases de datos relacional compatible con ACID, contenida en una relativamente pequeña (~275 kiB) biblioteca en C. SQLite es un proyecto de dominio público creado por D. Richard Hipp.

Es un simple apunte para luego trabajar junto a Python.

## Creando Tablas:
# Sentencia: create table [nombre de la tabla] ([nombre_campo1] [tipo_campo1] [opciones], [nombre_campo2] [tipo_campo2] [opciones] , ... , [nombre_campoN] [tipo_campoN] [opciones]);
# Ejem: create table User ( id integer(3) primary key autoincrement, nombre varchar(15) not null, grupo varchar(15) not null);


## Eliminando una tabla.
# Sentencia: drop table [nombre_tabla];
# Ejem: dropp table User;


## Cargando filas de datos.
# Sentencia: insert into [nombre_tabla](campos) values('valor campo1', 'valor campo2', ... , 'valor campoN');
# Ejem: insert into User(nombre, grupo) values('emmanuel_ar', 'root');
#         : insert into User(nombre, grupo) values('debianitram', 'admin');
#         : insert into User(nombre, grupo) values('guest', 'guest');

## Modificando Datos.
# Sentencia: update [nombre_tabla] set campoX = 'dato nuevo' where campoX = 'dato viejo';
# Ejem: update User set grupo = 'admin' where grupo ='root';

## Eliminar Registro.
# Sentencia: delete from [nombre_tabla] where campo='valor';
# Ejem: delete from User where id = '3';

## Buscando Datos.
# Sentencia simple: select * from [nombre_tabla];
# Ejem: select * from User;

Nota: El asterisco es un comodín, expresa "todo los campos".

## Buscar Ordenando los resultados por criterios.
# Sentencia: select [campo o comodín] from [nombre_tabla] order by [campoN] [opción];
# Ejem: select * from Datos order by nombre ASC;

Nota: Las opciones que se pueden utilizar son ASC, DESC.
ASC: ASCENDENTE.
DESC: DESCENDENTE.

## Busqueda por valores max, min, promedios o contar.
# Sentencia: select [expr] (tabla o comodín) from [tabla];
# Ejem: select max(id) from User;
#         : select count(*) from User;
#         : select sum(id) from User;
#         : select min(id) from User;


## Otro tipo de consultas: limit, operadores condicionales, etc.
# Sentencia: select [campoN] from [nombre_tabla] where [campoN] = '[condición]' limit x
Nota: Donde x es el número de registros a mostrar por el resultado de la consulta.
# Ejem: select * from User where grupo = 'admin' limit 2;

Nota: Se pueden utilizar los siguientes operadores con where: !=, =, >, <, <=, >=.


## Consulta por aproximación de texto.
# Sentencia: select [campoN o comodín] from [nombre tabla] where [campoN] like 'X%';
# Ejem: select nombre from User where nombre like'd%';

Nota: X indica con que letra debe de coincidir. % indica la posibilidad de más letras anteriores o posteriores según se coloque.