Si has llegado aquí mediante un buscador o por simple casualidad, te cuento que estas en la cuarta parte de un tutorial que empieza AQUI.
Como les había adelantado en la parte anterior, hoy empezaremos a trabajar en el Editor de Películas del Catálogo. Este editor sera el medio por el cual los usuarios podrán tanto agregar películas al catálogo, como editar la información de las que ya se encuentren cargadas. Tal como hicimos con la Ventana Principal, crearemos por un lado la Vista y por otro el Controlador. Dicho esto, empecemos a trabajar.
Codificando la Vista del Editor de películas
La clase que representa la Vista de nuestro Editor la llamaremos VistaEditorDePeliculas. Como les había comentado, el Editor sera invocado para realizar dos funciones distintas: agregar o modificar una película. Para que el Editor “sepa” en que modo lo estamos llamando, le pasaremos un parámetro. El parámetro lo llamaremos agregar y tendrá como valor por defecto True; es decir que si al invocarlo, no especificamos nada, el Editor se abrirá en modo “Agregar Película”. Además del modo en que queremos que se muestre el Editor, también le diremos quien es su ventana padre (en nuestro caso sera la Ventana Principal), y también recibirá una referencia a la aplicación en si, para poder acceder a los recursos (app.res) desde donde cargaremos la interface gráfica del dialogo, y también podremos saber cual es el modelo (app.modelo) de la aplicación. A continuación les muestro el código que implementa lo que les acabo de comentar:import wx
from wx import xrc
class VistaEditorDePelicula:
def __init__(self, parent, app, agregar=True):
self.modelo = app.modelo
self.app = app
self.Dialog = self.app.res.LoadDialog(parent, 'DlgEditorPelicula')
Con esto tenemos nuestro método __init__ casi terminado. Para finalizar agregaremos algo de código, para poder determinar si estamos en modo “Agregar” o “Editar”, y establecer el label del botón que guarda los cambios (btnAceptar) con el texto “Agregar” o “Guardar” según corresponda:
import wx
from wx import xrc
class VistaEditorDePelicula:
def __init__(self, parent, app, agregar=True):
self.modelo = app.modelo
self.app = app
self.Dialog = self.app.res.LoadDialog(parent, 'DlgEditorPelicula')
btnAgregarPelicula = xrc.XRCCTRL(self.Dialog, 'btnAceptar')
if(agregar):
btnAgregarPelicula.SetLabel('Agregar')
else:
btnAgregarPelicula.SetLabel('Guardar')
Por otro lado, debemos tener en cuenta que en caso que el Editor sea abierto en modo “Agregar”, basta con que el dialogo se muestre, pero si se abre en modo “Editar”, los controles del dialogo deben estar cargados con los datos correspondientes a la película que esta seleccionada en la Ventana Principal; para llevar a cabo esta tarea, codificaremos el método cargarPelicula. Este método recibirá el ID que tiene asignado la película en la base de datos, y haciendo uso del Modelo obtendremos los datos de esta, para luego cargar los controles correspondientes del Editor. Veamos como quedaría:
import wxComo pueden ver, el método cagarPelicula, llama al método obtenerInformacionDePelicula del Modelo, pasándole el ID de la película cuyos datos necesitamos. Tras esta llamada, tendremos el resultado en infoPelicula, y con estos cargamos los controles correspondientes al titulo y el año de la misma.
from wx import xrc
class VistaEditorDePelicula:
def __init__(self, parent, app, agregar=True):
self.modelo = app.modelo
self.app = app
self.Dialog = self.app.res.LoadDialog(parent, 'DlgEditorPelicula')
btnAgregarPelicula = xrc.XRCCTRL(self.Dialog, 'btnAceptar')
if(agregar):
btnAgregarPelicula.SetLabel('Agregar')
else:
btnAgregarPelicula.SetLabel('Guardar')
def cargarPelicula(self, idPelicula):
infoPelicula = pelicula.Pelicula()
infoPelicula = self.modelo.obtenerInformacionDePelicula(idPelicula)
titulo_pelicula = xrc.XRCCTRL(self.Dialog, 'txtTitulo')
anio_pelicula = xrc.XRCCTRL(self.Dialog, 'txtAnio')
titulo_pelicula.SetValue(infoPelicula.getTitulo())
anio_pelicula.SetValue(infoPelicula.getAnio())
Por si no lo recuerdan, el método obtenerInformacionDePelicula al que estamos llamando, aún no existe en nuestro Modelo, así que veamos como sería el código de este:
def obtenerInformacionDePelicula(self, idPelicula):Este método, tan sólo ejecuta una consulta a la base de datos para obtener la información de la película cuyo ID coincida con el que le enviamos como parámetro, y luego retorna esta información a quien lo haya invocado.
self.conectar()
self.cursor.execute("SELECT * FROM tblPeliculas WHERE IDPelicula = " + str(idPelicula))
resultado = self.cursor.fetchone()
infoPelicula = pelicula.Pelicula()
infoPelicula.setTitulo(str(resultado[1]))
infoPelicula.setAnio(str(resultado[2]))
self.desconectar()
return infoPelicula
Hasta ahora no tenemos la posibilidad de que se muestre el Editor, así que agregaremos un método a la Vista, llamado Mostrar para llevar a cabo esta tarea:
import wxLuego de terminar con esta clase, pasaremos a desarrollar el Controlador del Editor, el cual se encargara entre otras cosas de enviar a guardar los datos ingresados en los controles del Editor; es por esto que necesitamos crear un método en la Vista, que retorne lo que el usuario haya cargado; así que pasaremos a agregar el método getInfoPelicula:
from wx import xrc
class VistaEditorDePelicula:
def __init__(self, parent, app, agregar=True):
self.modelo = app.modelo
self.app = app
self.Dialog = self.app.res.LoadDialog(parent, 'DlgEditorPelicula')
btnAgregarPelicula = xrc.XRCCTRL(self.Dialog, 'btnAceptar')
if(agregar):
btnAgregarPelicula.SetLabel('Agregar')
else:
btnAgregarPelicula.SetLabel('Guardar')
def cargarPelicula(self, idPelicula):
infoPelicula = pelicula.Pelicula()
infoPelicula = self.modelo.obtenerInformacionDePelicula(idPelicula)
titulo_pelicula = xrc.XRCCTRL(self.Dialog, 'txtTitulo')
anio_pelicula = xrc.XRCCTRL(self.Dialog, 'txtAnio')
titulo_pelicula.SetValue(infoPelicula.getTitulo())
anio_pelicula.SetValue(infoPelicula.getAnio())
def Mostrar(self):
self.Dialog.ShowModal()
import wxEl método getInfoPelicula, simplemente obtiene los valores que el usuario introdujo en los controles y los carga en un objeto de la clase Pelicula, para luego retornarlo como resultado de su ejecución. Aun no hemos creado la clase Pelicula, así que pasemos a ver como seria:
from wx import xrc
class VistaEditorDePelicula:
def __init__(self, parent, app, agregar=True):
self.modelo = app.modelo
self.app = app
self.Dialog = self.app.res.LoadDialog(parent, 'DlgEditorPelicula')
btnAgregarPelicula = xrc.XRCCTRL(self.Dialog, 'btnAceptar')
if(agregar):
btnAgregarPelicula.SetLabel('Agregar')
else:
btnAgregarPelicula.SetLabel('Guardar')
def Mostrar(self):
self.Dialog.ShowModal()
def cargarPelicula(self, idPelicula):
infoPelicula = pelicula.Pelicula()
infoPelicula = self.modelo.obtenerInformacionDePelicula(idPelicula)
titulo_pelicula = xrc.XRCCTRL(self.Dialog, 'txtTitulo')
anio_pelicula = xrc.XRCCTRL(self.Dialog, 'txtAnio')
titulo_pelicula.SetValue(infoPelicula.getTitulo())
anio_pelicula.SetValue(infoPelicula.getAnio())
def getInfoPelicula(self):
infoPelicula = pelicula.Pelicula()
titulo_pelicula = xrc.XRCCTRL(self.Dialog, 'txtTitulo')
anio_pelicula = xrc.XRCCTRL(self.Dialog, 'txtAnio')
infoPelicula.setTitulo(titulo_pelicula.GetValue())
infoPelicula.setAnio(anio_pelicula.GetValue())
return infoPelicula
class Pelicula:De este modo, damos por terminada la Vista del Editor de películas y nos metemos de lleno con su Controlador.
def __init__(self):
self.titulo = ""
self.anio = ""
def setTitulo(self, titulo):
self.titulo = titulo
def getTitulo(self):
return self.titulo
def setAnio(self, anio):
self.anio = anio
def getAnio(self):
return self.anio
Codificando el Controlador del Editor de películas
El controlador del Editor sera el encargado de enviar a agregar o modificar la película según en que estado se encuentre abierto el Editor, es por esto que crearemos en este, los métodos onAgregarPelicula y onModificarPelicula:Claramente los dos métodos son muy parecidos, simplemente obtienen los datos cargados en la Vista a través del método getInfoPelicula que codificamos anteriormente, y llaman a al método agregarPelicula o modificarPelicula del Modelo según corresponda.
def onAgregarPelicula(self, evt):
infoPelicula = self.vista.getInfoPelicula()
self.app.modelo.agregarPelicula(infoPelicula.getTitulo(), infoPelicula.getAnio())
def onModificarPelicula(self, evt):
infoPelicula = self.vista.getInfoPelicula()
self.app.modelo.modificarPelicula(self.idPelicula, infoPelicula.getTitulo(), infoPelicula.getAnio())
Teniendo en cuenta que tenemos dos acciones posibles, debemos “asociar” el botón btnAceptar con una u otra función a la hora de crear la clase, es por esto que en el método __init__ (y al igual que hacíamos con la Vista) le pasamos el parámetro Agregar para determinar en que estado queremos mostrar el Editor, y así llevar a cabo la asociación. Para clarificar esto, veamos como quedaría la clase completa:
from vistas.vistaEditorDePelicula import VistaEditorDePelicula
import wx
from wx import xrc
import pelicula
class ControladorEditorDePelicula:
def __init__(self, app, parent, agregar=True):
self.app = app> self.vistaPrincipal = parent
self.vista = VistaEditorDePelicula(self.vistaPrincipal.frame, self.app, agregar)
btnAgregarPelicula = xrc.XRCCTRL(self.vista.Dialog, 'btnAceptar')
if(agregar):
self.vista.Dialog.Bind(wx.EVT_BUTTON, self.onAgregarPelicula, btnAgregarPelicula)
else:
self.idPelicula = app.controladorVistaPrincipal.vista.getIDItemSeleccionado()
self.vista.Dialog.Bind(wx.EVT_BUTTON, self.onModificarPelicula, btnAgregarPelicula)
self.vista.cargarPelicula(self.idPelicula)
self.vista.Mostrar()
def onAgregarPelicula(self, evt):
infoPelicula = self.vista.getInfoPelicula()
self.app.modelo.agregarPelicula(infoPelicula.getTitulo(), infoPelicula.getAnio())
def onModificarPelicula(self, evt):
infoPelicula = self.vista.getInfoPelicula()
self.app.modelo.modificarPelicula(self.idPelicula, infoPelicula.getTitulo(), infoPelicula.getAnio())
Pueden ver que el método __init__ comienza creando la Vista (a la cual le pasa los parámetros que tratamos oportunamente), luego determina si estamos en el modo “Agregar” o “Editar” y asocia el botón btnAceptar con el método onAgregarPelicula o onModificarPelicula; y por ultimo hace visible el Editor invocando el método Mostrar de la Vista del Editor. Para terminar, tan solo quiero que presten atención que si estamos en el modo de edición, obtenemos el ID de la película seleccionada en la Ventana Principal, y llamamos al método cargarPelicula de la Vista del Editor pasándoselo como parámetro, de este modo logramos que cuando aparezca el Editor en pantalla, este presente los datos de la película que el usuario quiere modificar.
Con esto terminamos esta cuarta parte del tutorial. En la próxima entrega haremos algunos cambios estéticos a nuestra pequeña aplicación (Agregaremos algunos iconos a la barra de herramientas, menues y botones) y también veremos como hacer para que podamos movernos entre las distintas películas del Catálogo directamente desde el Editor de Películas, sin necesidad de estar cerrándolo para pasar a modificar otra película.