Python y PyQT
Python y PyQT
Python y PyQT
Escribiremos una aplicacin completa para la gestin de pelculas de vdeo, escrita en Python. Partiendo desde cero llegaremos a disear hasta el propio instalador.
Introduccin
Al caer en el mundo de GNU/Linux, todo es nuevo y la primera pregunta que se realiza un programador es : En qu lenguaje y con qu programas puedo programar? Muchos respondern que en C o C++ , pero este es un lenguaje de alto nivel, en el cual algunas personas pueden perderse. Entonces nos podemos preguntar si habr algo parecido a Visual Basic pero para Linux, y ah es cuando se descubre Python, un lenguaje portado a diferentes sistemas operativos, muy potente a la vez que sencillo de programar y que adems suele venir instalado por defecto en la mayora de distribuciones de Linux. Pero una vez te acercas a Python, ves que se queda algo cojo con el tema visual, hasta que descubres que tiene unos bindings para QT, con lo cual ya puedes hacer aplicaciones KDE, sencillamente y tan solo instalando el PyQT. PyQT tiene una licencia GPL para Linux y MacOS. Para Windows tiene otro tipo de licencia comercial debido a que las libreras QT en Windows no son GPL, aunque Trolltech ha comentado que la versin QT4 ser GPL tambin en Windows(http://www.trolltech.com/newsroom/ann ouncements/00000192.html). Esto convertir la unin del lenguaje Python+PyQT en multiplataforma, una ventaja ms a la hora de crear nuestras aplicaciones. A todo esto le tenemos que sumar los numerosos y potentes mdulos de Python y la gran comunidad que hay alrededor de este lenguaje. En este artculo vamos a desarrollar una aplicacin completa, basada en Python, PyQT y PySQLite, que sirve para gestionar informacin sobre pelculas de vdeo. El cdigo completo de la misma est disponible en el CD-ROM de Mundo Linux.
MUNDO
Instalacin
Vamos a definir los programas que debemos de tener instalados para poder programar en PyQT, que sern Python y PyQT. En el CD-ROM que acompaa Mundo Linux se encuentra parte del software que se necesita para la instalacin en formato tar.gz, aunque siempre es ms sencillo acudir a los paquetes propios de la distribucin.
Python
Python: Suele venir preinstalado en la mayora de distribuciones de Linux, y est disponible en el CDROM. PyQT se puede descargar de: http://www.riverbankcomputing.co.uk/pyqt/index.php. Los usuarios de Debian pueden hacer:
apt-get install python2.4-qt3
El resto de los usuarios, despus de descomprimir tienen que hacer (se requiere Qt v3.x):
python configure.py make make install
QtDesigner
QtDesigner: Se recomienda buscar el paquete de su distribucin e instalarlo. Los usuarios de Debian pueden hacer:
apt-get install qt3-designer
Kdevelop
Kdevelop, aunque vale cualquier editor de cdigo fuente. Kdevelop se puede descargar de http://www.kdevelop.org. Los usuarios de Debian pueden hacer:
apt-get install kdevelop3
SQLite
SQLite es un motor de bases de datos GPL potente, rpido y sencillo de manejar; es el equivalente a una base de datos Access. Viene instalado por defecto en algunas distribuciones. Para comprobar que lo tenemos instalado ejecutamos el siguiente comando en consola:
sqlite3 -version
Linux
n81
40
http://digital.revistasprofesionales.com
Programacin
Si la versin es mayor de la 3.1 no necesitaremos instalarlo y si tenemos Debian tampoco, puesto que cuando instalemos pysqlite atraves de apt-get este instalar todas las dependencias. Si necesitamos instalarlo iremos a http://www.sqlite.org/ y lo descargaremos (en el CD-ROM se encuentra el fichero con las fuentes as como un binario precompilado para Linux). Para instalarlo ejecutaremos:
./configure make make install
Pysqlite
Ahora necesitaremos pysqlite, que es un mdulo que nos permitir usar en Python la base de datos SQLite. Lo descargamos de http://www.pysqlite.org (est disponible en el CD-ROM) y para instalarlo ejecutaremos:
python setup.py build python setup.py install
Primeros pasos
Una vez que tengamos instalados los programas necesarios, vamos a crear un ejemplo de una sencilla aplicacin con una base de datos para mantener ordenada nuestra coleccin de vdeos.
Ahora disearemos el formulario para nuestra aplicacin. En el asistente que aparece pulsaremos en Cancelar para disearlo nosotros. El formulario se puede disear como cada uno quiera, pero en este artculo proponemos un modelo. Primero, vamos a crear un GroupBox para agrupar los controles comunes en la insercin y visualizacin de nuestra coleccin de vdeos. Vamos a la seccin Containers y elegimos GroupBox. Seleccionamos un rea grande para poder introducir en ella todos los controles. Hacemos doble clic sobre este GroupBox y le ponemos un ttulo, como por ejemplo Coleccion de Vdeos. Ahora, dentro de este GroupBox vamos a introducir controles de la seccin Common Widgets. Empezamos con un TextLabel. Hacemos nuevamente doble clic y le ponemos lo que se muestra en la figura 3.
Figura 4. txtTitulo.
Despus insertaremos el componente ComboBox. Este componente es muy til cuando tenemos que elegir entre varias opciones; es muy intuitivo para el usuario y evita errores que se podran producir si se deja que el usuario introduzca la opcin por el teclado dentro de un LineEdit. A este ComboBox le pondremos el name cmbFormato, como hicimos con el control LineEdit. Hacemos clic sobre el ComboBox con el botn derecho y elegimos Edit; hacemos clic en New Item e insertamos DVD; volvemos a repetirlo e insertamos VHS, quedando como se muestra en la figura 5.
Figura 5. cmbFormato.
Figura 3. TextLabel.
El funcionamiento para insertar los dems controles es el mismo. Para no extendernos mucho el lector debera mirar cmo queda el formulario (vase figura 6) y explicaremos cmo darle funcionalidad a los botones existentes en el mismo.
Figura 1. QtDesigner.
Una vez que haya cargado el QtDesigner, se nos abrir un cuadro de dilogo y en la pestaa New File/Project elegiremos Main Window y pulsaremos OK (vase figura 2).
Ponemos ahora un LineEdit, pero en este control vamos a cambiar otra propiedad bastante importante y esta es el name. El name nos servir cuando estemos programando las funciones de la aplicacin para referirnos a los diferentes controles. Cambiamos el name y le ponemos txtTitulo, como se muestra en la figura 4. Ahora aadimos un Spacer. Este elemento nos aade una separacin entre los controles en los que est comprendido y es muy til a la hora de redimensionar un formulario. Ponemos otro TextLabel, con el ttulo Formato.
http://digital.revistasprofesionales.com
41
Linux
n81
Programacin
Listado 1
base.py
from pysqlite2 import dbapi2 as sqlite import string import os import sys defvariable_home(): home=os.environ.get(HOME) home=home+/.ColeccionVideos return home defcrear_base(): conn = abrir_conexion() cursor=conn.cursor() SQL=CREATE TABLE Videos (Cod float, Titulo varchar, Formato varchar, Genero varchar, Anio integer, Director varchar, Actores varchar, Argumento varchar, PRIMARY KEY(Cod)) cursor.execute(SQL) conn.commit() cursor.close() conn.close() definsertar (cod,titulo,formato,genero,anio,director,actores,argumento): conn = abrir_conexion() cursor=conn.cursor() SQL = INSERT into Videos (Cod , Titulo , Formato , Genero , Anio , Director , Actores , Argumento) values ( + str(cod) + , + str(titulo) + , + str(formato) + , + str(genero) + , + str(anio) + , + str(director) + , + str(actores) + , + str(argumento) + ) cursor.execute(SQL) conn.commit() cursor.close() conn.close() defactualizar (cod,titulo,formato,genero,anio,director,actores,argumento): conn=abrir_conexion() cursor=conn.cursor() SQL = UPDATE Videos SET Titulo= + str(titulo) + , Genero= + str(genero) + , Anio= + str(anio) + , Director= + str(director) + , Actores= + str(actores) + , Argumento= + str(argumento) + WHERE Cod= + str(cod) cursor.execute(SQL) conn.commit() cursor.close() conn.close() defabrir_conexion(): # Crea conexion a la Base de Datos Sqlite rutadb=variable_home() + /sqlite.db conexion=sqlite.connect(database=rutadb) return conexion defcrear_archivo(): if not os.path.exists(variable_home()): os.makedirs(variable_home()) archivo = open(variable_home() + /sqlite.db,w) archivo.close() defultimo_video(): try: conn=abrir_conexion() cursor=conn.cursor() SQL=SELECT Cod FROM Videos ORDER BY Cod DESC cursor.execute(SQL) row=cursor.fetchone() ultimo=row[0] cursor.close() conn.close() except: crear_archivo() crear_base() ultimo=0 return ultimo
control le damos el nombre de txtArgumento. El siguiente control que nos encontramos es un Botn. El control se llama PushBoton y aparte de llamarle btnGuardar le aadiremos un evento que se activar cuando hagamos clic sobre l. Para activar este evento haremos clic sobre el botn y miraremos las propiedades. Nos posicionaremos en la pestaa Signal Handlers; haremos clic sobre el evento clicked(); una vez hecho esto nos preguntar si queremos guardar el archivo ui.h y le diremos que s (vase figura 7).
Figura 7. btnGuardar.
Pues as procederemos con los dems botones a los que llamaremos, por orden, btnPrimero, btnAnterior, btnSiguiente, btnUltimo, btnInsertar. Con esto ya tendremos acabada la parte del diseo del formulario.
Siguiendo con el orden de los nombres de los controles, el ComboBox de Gnero se llamara cmbGenero y se aadirn los siguientes elementos: Accin, Blico, Ciencia Ficcin, Comedia, Animacin, Documental, Drama, Thriller, Musical, Terror. El name de ao txtAnio, el de Director txtDirector, el de Actores txtActores.
MUNDO
El siguiente control que nos encontramos es TextEdit; es un control que sirve para insertar textos muy largos, como por ejemplo el argumento de la pelcula. Para que el control fuera ms vistoso, hemos dejado siempre visible la barra de desplazamiento vertical. Esto se consigue poniendo la propiedad vScrollBarMode a Always On. A este
Linux
n81
42
http://digital.revistasprofesionales.com
Programacin
Listado 2
if self.aux==0 :
def btnGuardar_clicked(self):
actualizar(self.codigo,self.txtTitulo.text(),self.cmbFormato.currentText(),sel f.cmbGenero.currentText(),self.txtAnio.text(),self.txtDirector.text(),self.txt Actores.text(),self.txtArgumento.text()) if self.aux==1 : self.ultimo=self.ultimo+1 insertar(self.ultimo,self.txtTitulo.text(),self.cmbFormato.currentText(),self. cmbGenero.currentText(),self.txtAnio.text(),self.txtDirector.text(),self.txtAc tores.text(),self.txtArgumento.text()) QMessageBox.information(self,Informacion,SE HA AGREGADO CORRECTAMENTE) self.aux=0 self.codigo=self.ultimo
En este artculo no se van a explicar las funcionalidades de Kdevelop, tan solo lo vamos a usar para editar nuestro cdigo. Para abrir los archivos de Python con Kdevelop tenemos que hacer clic con el botn derecho sobre el archivo Python, elegir Abrir con ... poner kdevelop3 y marcar la opcin Recordar asociacin de programa para este tipo de archivo.
Listado 3
borrar_elementos
Listado 4
btnAnterior_clicked
if self.codigo > 1 : self.codigo=self.codigo-1 conn=abrir_conexion() cursor=conn.cursor() SQL = SELECT * FROM Videos WHERE Cod=+str(self.codigo) cursor.execute(SQL) row = cursor.fetchone() self.codigo=row[0] self.txtTitulo.setText(row[1]) self.cmbFormato.setCurrentText(row[2]) self.cmbGenero.setCurrentText(row[3]) self.txtAnio.setText(str(row[4])) self.txtDirector.setText(row[5]) self.txtActores.setText(row[6]) self.txtArgumento.setText(row[7]) cursor.close() conn.close() else : QMessageBox.information(self,Primer Registro,NO HAY MAS REGISTROS)
La siguiente lnea:?
import sys
Si queremos que nuestro programa se convierta en ejecutable, en modo root hacemos lo siguiente:
chmod a+x <nombre de la aplicacin>.py
Listado 5
btnSiguiente_clicked
Programando la aplicacin
Ahora tendremos que aadirle la funcionalidad a nuestros botones y crear la conexin con la base de datos. Antes de ponernos a crear objetos de PyQT, podemos echar un vistazo al API de estos objetos en http://doc.trolltech.com/ 3.3/. De esta manera, ojeando el API y siguiendo los cambios efectuados en este artculo, no nos ser difcil comprender las modificaciones requeridas en otros objetos. Creamos un nuevo archivo llamado base.py y le aadimos el cdigo que se muestra en el listado 1. Este archivo contendr las funciones bsicas para atacar la base de datos, es decir,
MUNDO
if self.codigo < self.ultimo : self.codigo=self.codigo+1 conn=abrir_conexion() cursor=conn.cursor() SQL = SELECT * FROM Videos WHERE Cod=+str(self.codigo) cursor.execute(SQL) row = cursor.fetchone() self.codigo=row[0] self.txtTitulo.setText(row[1]) self.cmbFormato.setCurrentText(row[2]) self.cmbGenero.setCurrentText(row[3]) self.txtAnio.setText(str(row[4])) self.txtDirector.setText(row[5]) self.txtActores.setText(row[6]) self.txtArgumento.setText(row[7]) cursor.close() conn.close() else : QMessageBox.information(self,Ultimo Registro,NO HAY MAS REGISTROS)
http://digital.revistasprofesionales.com
43
Linux
n81
Programacin
Listado 6
btnUltimo_clicked
Listado 7
btnPrimero_clicked
conn=abrir_conexion() cursor=conn.cursor() SQL = SELECT * FROM Videos WHERE Cod=+str(self.ultimo) cursor.execute(SQL) row = cursor.fetchone() if self.codigo !=0: self.codigo=row[0] self.txtTitulo.setText(row[1]) self.cmbFormato.setCurrentText(row[2]) self.cmbGenero.setCurrentText(row[3]) self.txtAnio.setText(str(row[4])) self.txtDirector.setText(row[5]) self.txtActores.setText(row[6]) self.txtArgumento.setText(row[7]) cursor.close() conn.close()
conn=abrir_conexion() cursor=conn.cursor() SQL = SELECT * FROM Videos WHERE Cod=+str(1) cursor.execute(SQL) row = cursor.fetchone() if self.codigo !=0 : self.codigo=row[0] self.txtTitulo.setText(row[1]) self.cmbFormato.setCurrentText(row[2]) self.cmbGenero.setCurrentText(row[3]) self.txtAnio.setText(str(row[4])) self.txtDirector.setText(row[5]) self.txtActores.setText(row[6]) self.txtArgumento.setText(row[7]) cursor.close() conn.close()
la conexin, la creacin de la base de datos y la insercin y actualizacin de registros. Tambin definir el directorio donde se va a copiar la base de datos. En este caso se copiar en la HOME del usuario dentro del directorio .ColeccionVideos (el punto indica que este directorio es oculto). De esta manera podemos tener varios usuarios con su propia base de datos de su coleccin de vdeos, diferente a la de los otros usuarios. Ahora, dentro de nuestro archivo principal coleccion.py debemos aadir la siguiente lnea:
from base import *
Listado 8
languageChange
Esto nos permitir usar las funciones de la base de datos dentro de nuestro formulario. Buscaremos la funcin def btnGuardar_ clicked(self): y le aadiremos el cdigo que se muestra en el listado 2. Este cdigo es el correspondiente al botn Guardar y comprueba si el registro que pretendemos guardar ya existe y necesitamos actualizarlo o es nuevo y necesitamos insertar un nuevo registro. En esta funcin encontramos una funcin de PyQT que nos muestra un mensaje de informacin por pantalla:
QMessageBox.information(self, Informacion,SE HA AGREGADO CORRECTAMENTE)
self.aux=0 self.ultimo=ultimo_video() conn=abrir_conexion() cursor=conn.cursor() SQL = SELECT * FROM Videos ORDER BY Cod ASC cursor.execute(SQL) row = cursor.fetchone() try: self.codigo=row[0] self.txtTitulo.setText(row[1]) self.cmbFormato.setCurrentText(row[2]) self.cmbGenero.setCurrentText(row[3]) self.txtAnio.setText(str(row[4])) self.txtDirector.setText(row[5]) self.txtActores.setText(row[6]) self.txtArgumento.setText(row[7]) except: self.codigo=0 cursor.close() conn.close()
self.aux=1
Y debajo de def btnInsertar_clicked(self): insertaremos la funcin que se muestra en el listado 3. Observamos que en PyQT la llamada a las diferentes funciones de los objetos (mirar el API de estas funciones) se realiza de la siguiente manera:
Objeto.funcion
Para pasarlo de QT a PyQT hemos cambiado 2 cosas: hemos cambiado los :: por . y this por self. Con esto ya tenemos este cdigo funcional en nuestra aplicacin. Buscaremos la funcin def btnInsertar_ clicked(self): y le aadiremos el siguiente cdigo :
self.borrar_elementos() MUNDO
Buscaremos la funcin def btnAnterior_ clicked(self): y le aadiremos el cdigo que muestra el listado 4. Buscaremos la funcin def btnSiguiente_ clicked(self): y le aadiremos el cdigo que se muestra en el listado 5. Buscaremos la funcin def btnUltimo_ clicked(self): y le aadiremos el cdigo que se muestra en el listado 6. Buscaremos la funcin def btnPrimero_ clicked(self): y le aadiremos el cdigo que se muestra en el listado 7. Y, por ltimo, incluiremos el cdigo que se muestra en el listado 8 al final de la funcin def languageChange(self): . Con esto ya tendremos nuestra aplicacin funcionando.
Paso 1
Crearemos un archivo llamado setup.py, que ser el encargado de automatizar el proceso de instalacin. En este archivo introducimos el cdigo que se muestra en el listado 9. Este archivo comprobar que tenemos instalados todos los programas necesarios para que la aplicacin funcione y proceder a copiar los archivos al directorio apropiado. Tambin copiar el archivo coleccionvideo .desktop, que ser el encargado de crear una entrada en el men del escritorio.
Paso 2
Creacin del archivo coleccion.desktop que contendr el texto que se muestra en el listado 10.
Linux
n81
44
http://digital.revistasprofesionales.com
Programacin
Listado 9
setup.py
de la aplicacion>.py
import sys import os from qt import qVersion, PYQT_VERSION_STR from pysqlite2 import dbapi2 as sqlite pythonVersion = sys.version_info ifpythonVersion < (2, 3, 4) : print ################################################################# print You need Python 2.3.4 or greater to install . Exiting... print ################################################################# sys.exit(1) qtVersion = qVersion() ifqtVersion < 3.2.3 : print ################################################################# print You need Qt 3.2.3 or greater to install . Exiting... print ################################################################# sys.exit(1) pyqtVersion = PYQT_VERSION_STR ifpyqtVersion < 3.12 : print ################################################################# print You need PyQt 3.12 or greater to install . Exiting... print ################################################################# sys.exit(1) ifsqlite.version < 2.0.3 : print ################################################################# print You need pysqlite 2.0.3 or greater to install . Exiting... print ################################################################# sys.exit(1) # ================================================================= printInstalling ...\n pathN=/usr/share/apps/ appName=coleccionvideo/ pathN=pathN+appName ifnot os.path.exists(pathN): os.makedirs(pathN) printCopying files ...\n os.system(cp -f base.py + pathN ) os.system(cp -f coleccion.py + pathN ) os.system(cp -f icono.xpm + pathN ) os.system(chmod +x coleccion.py + pathN ) pathD=/usr/share/applications os.system(cp -f coleccionvideo.desktop + pathD ) printInstallation complete.
En Icon ir la ruta del icono, que en este caso est en /usr/share/apps/coleccionvideo/icono.xpm. En Categories ir la categora donde queramos que se muestre nuestra aplicacin; en este caso ser en Oficina. En Comment ir un comentario sobre nuestra aplicacin. En Terminal ir un 1 si queremos que la aplicacin se abra en una ventana de terminal y 0 si no queremos que se abra esta ventana. En Type ir el tipo de entrada de los 4 posibles: Application, Link, FSDevice y Directory. En este caso Application por que es una aplicacin.
Paso 3
Creacin de un icono para nuestra aplicacin llamado icono.xpm (puede llevar otras extensiones). Ms informacin sobre la creacin del icono en http://artist.kde.org/ applications.html.
Paso 4
Crear un archivo llamado README o INSTALL donde se muestren las instrucciones de instalacin. En este caso, para instalar la aplicacin tan solo es necesario ejecutar:
# python setup.py
Nota: # significa que ese archivo se debe ejecutar como root. Para ello, antes ejecutar:
$ su Password:(teclear el password de root)
Una vez ejecutado este script aparecer en nuestro men del escritorio, en la entrada de Oficina, una entrada de nuestra aplicacin con su icono (vase figura 8).
Listado 10
coleccion.desktop
[Desktop Entry]?Name=ColeccionVideos Exec=python /usr/share/apps/coleccionvideo/coleccion.py Icon=/usr/share/apps/coleccionvideo/icono.xpm Categories=Application;Office; Comment=Mi Coleccion de Videos Terminal=0 Type=Application
Paso 5
Ahora ya solo nos queda empaquetar estos archivos en un archivo.tar.gz. Para esto nos hemos de situar dentro del mismo directorio y ejecutar:
tar zcvf coleccionvideo.tar.gz *
Referencias
G API de la librera QT: http://doc.trolltech.com/3.3/ G PyQT: http://www.riverbankcomputing.co.uk/pyqt/index.php G SQLite: http://www.sqlite.org/ G PySQLite: http://www.pysqlite.org G Python: http://www.python.org/ G Lista usuarios de Python en espaol: http://listas.aditel.org/listinfo/python-es G Kdevelop: http://www.kdevelop.org/
Y con esto habremos terminado. En el CDROM que acompaa la revista se incluye el cdigo completo de la aplicacin, as como el software utilizado. Esperamos que este ejemplo haya resultado sencillo e interesante al mismo tiempo.
MUNDO
http://digital.revistasprofesionales.com
45
Linux
n81