interfaces gráficas con wxpython

Upload: aprender-libre

Post on 05-Apr-2018

213 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/31/2019 Interfaces grficas con wxPython

    1/6

  • 7/31/2019 Interfaces grficas con wxPython

    2/6

    Programacin

    wxWindows comenz su andadura en 1992en el Artificial Intelligence ApplicationsInstitute de la Universidad de Edinburgo, y sur-gi de la idea de Julian Smart cuando se plan-te la necesidad de escribir una aplicacin quedeba funcionar tanto en Windows como enterminales con X-Window. Dado que las herra-mientas comerciales no estaban a su alcance,decidi escribir su propia librera que, con elpaso del tiempo y con la ayuda de otras perso-nas, termin convirtindose en un proyecto deOpen Source y en lo que hoy es wxWindows (law viene de Windows y la x de X-Window).Actualme se rige bajo la licencia denominadawxWindows license que bsicamente es lalicencia L-GPL con la salvedad de que puedenlicenciarse otros productos propietarios quetomen slo los binarios de esta librera. Conello los autores pretenden por un lado que sea

    software Open Source y por otro satisfacer lasnecesidades de aquellos que pretenden cos-truir software propietario incluyendo wxWin-dowscomo librera base para la GUI. La licen-cia en cuestin ha sido aprobada por la OpenSource Initiative, que se encarga de gestionarlas distintas licencias que existen en el mundoOpen Source.

    wxPython

    El lenguaje Python gana cada da ms adeptosdebido a sus principales caractersticas: rapidezde ejecucin, multiplataforma y las ventajas pro-pias de un lenguaje de scripting orientado aobjetos. Cuando deseamos escribir una GUI utili-zando este lenguaje disponemos de diversasopciones: pyQT, pyGTK, Tkinter o wxPython. Estaltima es, bsicamente, la versin de wxWin-dows para Python. Se trata de un completo tool-kit para construir elementos de interfaces grfi-cas de usuario. Utilizar esta librera nos permiti-r escribir aplicaciones multiplataforma con unacompleta GUI. Evidentemente, si ya conocemoswxWindows tendremos mucho camino avanzadodebido a que la API es prcticamente igual, sal-vando las distintas sintcticas que existen entre

    Python y C++ (recordemos que originariamentewxWindows fue desarrollada para este lenguaje).Por otro lado, wxWindows est dotada de unagran estabilidad y se viene utilizando desde hacediez aos.

    wxPython es un mdulo de Python ms quepodemos incorporar en nuestros programas. Estemdulo nos permite crear instancias de las clasesde wxWindows e invocar a sus mtodos. Todas laclases son prcticamente iguales en ambas libre-ras, salvando las distancias entre los lenguajes,por lo que la documentacin sobre wxWindowsnos valdr perfectamente para desarrollar conwxPython.

    A partir de aqu asumiremos que el lectorconoce el lenguaje Python o est familiarizadocon l. Como punto de partida recomendamos elartculo que sobre este lenguaje aparce enMundo Linux53.

    Instalacin

    En primer lugar debemos tener instalado el intr-prete de Python, para la realizacin de este art-culo nosotros hemos utilizando la versin 2.1.3.Habitualmente podemos encontrarlo en todas lasdistribuciones de Linux. Posteriormente debemosinstalar la versin de wxWindows para Linux, queen este caso utiliza las libreras de GTK+, es loque se conoce con el nombre de wxGTK. No olvi-demos que antes de instalar esta librera, nuestro

    sistema debe contar con el toolkit de GTK+. Siutilizamos Gnome seguro que ya las tenemosinstaladas. GTK+ es utilizado por muchos progra-mas, seguramente nuestro sistema ya cuenta conestas libreras. Por ltimo, slo nos queda insta-lar wxPython. Todo este software se distribuye enformato tarbally para instalarlo se sigue el pro-ceso habitual para el software empaquetado eneste formato, es decir, debemos descromprimir ycompilar. Si tenemos la suerte de utilizar Debianel proceso se simplifica: basta con instalar elpaquete libwxgtk2.2-python (en caso de Python2), que adems nos configurar el mdulo y nosdejar todo listo para empezar a trabajar.

    Linux51 MUNDO

    Interfaces grficas con wxPython

    1 from wxPython.wx import *2 app = wxPySimpleApp()3 frame = wxFrame(None, -1, Hello World!)4 frame.Show(1)5 app.MainLoop()

    Listado 1 La aplicacin Hello World!

    Figura 2.Nuestra primera aplicacin.

  • 7/31/2019 Interfaces grficas con wxPython

    3/6

    Programacin

    El mdulo wxPython debe quedar localizado

    en el directorio site-packages de Python. En elcaso de Debian se trata del directorio/usr/lib/python2.1/site-packages/wxPython/.Dado que el mdulo se encuentra en este direc-torio, no tendremos ningn problema a la horade realizar la importacin del mismo desdenuestros programas.

    La ltima versin liberada de wxPython es la2.4.1.2, la cual necesita la versin 2.4 de wxGTK.Sin embargo, para la realizacin de este artcu-lo nosotros hemos utilizado la versin 2.2, dadoque se trata de la versin estable incluida enDebian Woody.

    Para comprobar que tenemos correctamenteinstalado wxPython, podemos abrir una shell, eje-cutar python y teclear from wxPython.wx import*. Si todo va bien, la lnea de comandos del intr-prete nos mostrar otra lnea. Ver figura 1.

    Hello World!

    En lugar de describir o resumir la API que presen-ta wxPython, pensamos que es ms interesantecomenzar viendo un caso prctico que nos ayude

    a empezar a programar de forma rpida. En cual-quier caso podemos encontrar en la web (verreferencias) amplia informacin sobre todo elconjunto de widgetsque nos ofrece wxWindowsy wxPython, que seguro nos servir para ir pro-fundizando y sacar amplio partido para el desa-rrollo de interfaces grficas de usuario en Python.

    Como introduccin hemos elegido todo unclsico: Hello World!. Nuestra primera aplicacinser una ventana que presenta el tradicionalmensaje. El cdigo est en el listado 1.

    Lo primero que debemos tener en cuenta esque wxPython est dirigido a eventos, es decir,cada control utiliza una rutina de callback queresponde a cierto evento. La primera lnea decdigo indica el mdulo que debemos importar yqu clases. En este caso hemos utilizado el aste-risco (*) para importar todas las clases, aunquepodamos haber importado slo aquellas que

    vamos a utilizar. Seguidamente indicamos queesta va a ser una aplicacin wxPython (lnea 2),esto implica que est dirigida a eventos y quedebe establecerse un ciclo inicial (esto se indicaen la lnea 5). El nico control que tiene nuestraaplicacin es un wxFrame. Debemos pensar enframes y no en ventanas, ya que un frame es uncontenedor de controles. La lnea 3 presenta lacreacin de nuestro wxFrame, los parmetrosque recibe este constructor son el padre delwxFrame, su IDy el mensaje de texto que apare-ce como ttulo. En este caso hemos elegido par-metros por defecto para indicar que estewxFrameno tiene padre. Solo nos resta mostrarel wxFrame en pantalla, para ello utilizamos elmtodo Show. El resultado puede apreciarse enla figura 2.

    Caso prctico

    Obviamente, una aplicacin con una GUI tienems que un simple ventana. En este apartadomostraremos, a travs de un ejemplo ms com-pleto, los principales controles y mtodos quepodemos utilizar con wxPython para conseguiruna GUI consistente. Como caso prctico vamosa realizar una aplicacin que genere un fichero a

    partir de unos valores que introduce el usuario.Este fichero resultado nos servir para configurarun acceso JDBC para el servidor de aplicacionesJ2EE JBoss. La motivacin del desarrollo de estaaplicacin viene dada por el hecho de que pararealizar esta configuracin, JBoss no facilita nin-guna herramienta automtica. Asimismo, podre-mos comprobar la ventaja de realizar esta aplica-cin en Python en lugar de utilizar Java, que seralo normal, dado que estamos hablando de JBoss.Se trata de utilizar dos lenguajes de programa-cin con un objetivo comn. Normalmente, setiende a utilizar el mismo lenguaje de programa-cin cuando intentamos resolver un problema

    Linux 52MUNDO

    1 ID_MENU_EXIT = 1012 ID_MENU_ABOUT = 102

    3 self.CreateStatusBar()4 self.SetStatusText(Welcome!)

    5 # MenuBar6 menuBar = wxMenuBar()7 menu = wxMenu()8 menu.Append(ID_MENU_ABOUT, A&bout, About...)9 menu.Append(ID_MENU_EXIT, E&xit, Close application)

    10 EVT_MENU(self, ID_MENU_EXIT, self.OnbtnClose)11 EVT_MENU(self, ID_MENU_ABOUT, self.OnbtnAbout)

    12 menuBar.Append(menu, &File)13 self.SetMenuBar(menuBar)

    14 def OnbtnClose(self, evt):15 self.Close()

    Listado 2 Men, barra de estado y mtodos callback

    Figura 3.Nuestra aplicacin.

  • 7/31/2019 Interfaces grficas con wxPython

    4/6

    Programacin

    dado. Sin embargo, es interesante evaluar qulenguaje es ms apropiado para qu tarea eintentar que ambos puedan encajar entre s. Espor ello que decidimos realizar la aplicacinmencionada en Python, aunque finalmente nosservir para configurar JBoss y correr aplicacio-nes escritas en Java. Adems, esta aplicacin nosservir para entrar en contacto con wxPython.Proponemos al lector y programador de Java queescriba la misma aplicacin en este lenguaje y locompare con el que aqu presentamos.

    En concreto, la aplicacin pedir al usuariouna serie de valores para generar el fichero XML

    que sirve para configurar un pool de conexionesa base de datos y su DataSource asociado. Siestamos familiarizados con el desarollo J2EEestos valores nos sern populares. Podemosgenerar un fichero para los siguientes gestoresde bases de datos: PostgreSQL, MySQL, Oracle,DB2, Informix y Sybase.

    Empecemos con el cdigo. Creamos una clasellamada MainFrame que herede de la clasewxFrame. Esta clase ser el contenedor de con-troles y tendr mtodos callback para respondera la accin del usuario sobre dichos controles. Elconstructor de esta clase ser el encargado decrear cada control.

    El listado 2 nos muestra la creacin de unabarra de men, el acceso a la barra de status y laconexin de los mtodos callback. Cuando seproduce un evento, wxPython captura el mensa-

    je y realiza una llamada a un mtodo de nuestraaplicacin. Para ello debemos hacer un registroque conecte la sucesin de un evento a un mto-do concreto. Pues bien, estos mtodos comien-zan por EVT_. Veamos la lnea 10. A travs de la

    Linux53 MUNDO

    Interfaces grficas con wxPython

    1 lblUser = wxStaticText(self.panel, -1, DB user: ,wxPoint(20,110))2 self.txtUser = wxTextCtrl(self.panel, -1, ,wxPoint(140,110))

    3 # criteria combo4 arrCriteria = [ByContainerAndApplication, ByContainer, ByApplication, ByNothing]

    5 self.cbCriteria = wxComboBox(self.panel, ID_CBCRITERIA, arrCriteria[1], wxPoint(140, 230), wxSize(440, -1),arrCriteria, wxCB_DROPDOWN)

    6 btnClose = wxButton(self.panel, ID_BTNCLOSE, Close, wxPoint(220, 270), wxSize(80, 25))

    Listado 3 Etiquetas, cajas de texto y combo

    1 ID_CBURL = 302 ID_CBDRIVER = 403 urlList = [jdbc:oracle:thin:@[servername]:[port]:[database name],

    jdbc:oracle:thin:@[servername]:[port]:[database name],jdbc:mysql://[servername]:[port]/[database name],jdbc:postgresql://[servername]:[port]/[database name],jdbc:db2:[database name],jdbc:informixsqli://[host].[domain]:[port]/[databasename]:INFORMIXSERVER=[server],jdbc:sybase:Tds:[host].[domain]:[port]/[databasename]?JCONNECT_VERSION=6 ]

    4 driverList = [oracle.jdbc.driver.OracleDriveroracle.jdbc.xa.client.OracleXADataSource,org.gjt.mm.mysql.Driver,org.postgresql.Driver,COM.ibm.db2.jdbc.app.DB2Driver,com.informix.jdbc.IfxDriver,com.sybase.jdbc2.jdbc.SybDataSource ]

    5 self.cbDriver = wxComboBox(self.panel, ID_CBDRIVER, driverList[0], wxPoint(140,70), wxSize(440, -1), driverList, wxCB_DROPDOWN)

    6 self.cbUrl = wxComboBox(self.panel, ID_CBURL, urlList[0], wxPoint(140, 30),wxSize(440, -1), urlList, wxCB_DROPDOWN)

    7 EVT_COMBOBOX(self, ID_CBURL, self.OnChangecbUrl)8 def OnChangecbUrl(self, evt):

    self.cbDriver.SetSelection(self.cbUrl.GetSelection())9 EVT_COMBOBOX(self, ID_CBDRIVER, self.OnChangecbDriver)10 def OnChangecbDriver(self, evt):

    self.cbUrl.SetSelection(self.cbDriver.GetSelection())

    Listado 4 Comboboxes

    Figura 4.Salvando un fichero.

  • 7/31/2019 Interfaces grficas con wxPython

    5/6

    Programacin

    llamada a EVT_MENU() estamos indicando quecuando se produzca un evento relacionado con labarra de men y que afecte a la entrada indenti-ficada por ID_MENU_EXIT, se debe llamar almtodo OnbtnClose de nuestra aplicacin. Esteidentificador est asociado a la entrada Close

    application del men (lnea 9). El mtodoonbtnClose() se encarga de cerrar el wxFrame,observemos que necesita el parmetro evt el cualle indica que debe responder a un evento. La cre-acin del men y de la barra de status se hace enlas lneas 6 y 7 respectivamente. Posteriormente,se aaden las entradas al men, que en nuestrocaso son slo dos: About y Exit. Los ID de cadacontrol son nmeros que no atienden a un crite-rio concreto, simplemente deben ser distintospara cada control y nos sirven para identificarlosde forma unvoca en las llamadas a los mtodos.

    Pasamos a ver los principales controles queutiliza nuestra aplicacin ejemplo:q Botonesq Etiquetas de textoq Elementos desplegables (comboboxes)q Cajas de textoq Cuadros de dilogo modales

    Comezamos observando la lnea 1 del listado3, en ella se crea una etiqueta de texto. En estecaso concreto se trata de la etiqueta que indicael nombre de usuario. El ltimo parmetro indi-ca, a travs de una funcin, la posicin relativade la etiqueta respecto al frame. La siguientelnea sirve para crear una caja de texto donde se

    podr introducir el nombre del usuario. El tercerargumento de la funcin es la cadena vaca por-que inicialmente no queremos que se muestreningn valor en la caja de texto. Las lneas 5 y 6crean un combo donde se podr seleccionar elcriterio de manejo del pool de conexiones por

    parte de Jboss. El tercer argumento de la funcinwxComboBox es la lista de los criterios seleccio-nables por el usuario. En nuestro caso utilizamosla lista arrCriteria. La ltima lnea del listadoindica la creacin de un botn que sirve paracerrar la aplicacin.

    Con el objetivo de facilitar el trabajo al usua-rio, nuestra aplicacin seleccionar de formaautomtica el driver y su URL apropiada. Es decir,una vez seleccionado el valor en uno de los com-bos, se dispara un evento que marca el valorcorrespondiente en el otro combo. Con esto evi-tamos que el usuario pueda seleccionar un driverque no corresponde con su URL y viceversa. El lis-tado 4 nos muestra el cdigo en cuestin. Unavez creados los dos combos, registramos losmtodos que responden al evento de cambio delvalor seleccionado en dichos combos. Debemosregistrar un mtodo para cada combobox. Laslneas 8 y 9 muestran el mtodo que se va a eje-cutar cuando cambie el texto del combo de lasURL. En primer lugar se obtiene el ndice del ele-mento seleccionado de la lista de los valores dedicho combo (mtodo GetSelection()), y poste-riormente se selecciona el driver correspondienteen el otro combo (mtodo SetSelection()). Laslistas de ambos combos tienen el mismo nmero

    de elementos, por ello basta con indicar su ndi-ce para seleccionar el valor correspondiente.

    Por ltimo, veremos los cuadros de dilogomodales que utiliza nuestra aplicacin. El cuadroms sencillo que podemos crear con wxPython esaquel que tiene un botn, un mensaje y un icono.Recordemos que la aplicacin que estamos anali-zando se encarga de generar un fichero XML.Pues bien, si este se ha generado correctamentese informa al usuario de ello a travs de uno deestos cuadros modales. Vemoslo en las lneas 7 y8 del listado 5. El segundo argumento de la fun-cin wxMessageDialog() es el mensaje mostradoal usuario y el tercer argumento es el icono.

    Linux 54MUNDO

    1 dlg = wxFileDialog(self, Save a text file,, , XML Files(*.xml)|*.xml|Allfiles(*.*)|*.*|, wxSAVE);

    2 if dlg.ShowModal() == wxID_OK:3 filename = dlg.GetFilename()4 dirname = dlg.GetDirectory()5 try:6 self.CreateFileJBoss(path.join(dirname, filename))7 dlgMsg = wxMessageDialog(self.panel, File generated sucessfully!,

    style = wxOK);8 dlgMsg.ShowModal()9 except:10 dlgMsg = wxMessageDialog(self.panel, Error! File not generated,

    style = wxICON_ERROR);11 dlgMsg.ShowModal()

    Listado 5 Cuadros de dilogo modales.

    Figura 5.Cuadro de dilogo.

  • 7/31/2019 Interfaces grficas con wxPython

    6/6

    Programacin

    El mtodo ShowModal() muestra el cuadro enpantalla. Habremos observado que estas lneasse encuentran dentro de un bloque try-except,se trata del manejo de excepciones que nosofrece Python. En caso de que ocurra una excep-cin al generar el fichero, se ejecutar el cdigodel bloque except, que en este caso muestra otrocuadro de dilogo indicndole al usuario que haocurrido un error. En las dos primeras lneas dellistado 5 podemos ver la creacin de otro cuadromodal distinto. Se trata del tpico cuadro Saveas... que permite al usuario guardar un ficheroen un directorio del sistema de ficheros. La fun-cin se llama wxFileDialog y recibe como par-metros el ttulo del cuadro de dilogo, el tipo deficheros que debe mostrar y una constante queindica el tipo de cuadro, en este caso wxSAVE.Observemos cmo en la lnea 2 preguntamos siel mtodo ShowModal() es igual a wxID_OK, en

    cuyo caso pasaremos a la creacin del fichero.Esta condicin se dar cuando el usuario selec-cione el nombre del fichero a salvar y pulse elbotn OK. La aplicacin estar esperando a quese produzca ese evento.

    Conclusiones

    Esperamos que este artculo le haya servido allector de aproximacin al mundo de wxPython. Atravs de un ejemplo concreto, hemos pretendi-do realizar un vistazo a las posibilidades quepuede ofrecernos este mdulo de Python. Comohemos podido comprobar, se trata de una com-pleta librera para escribir aplicaciones con unaGUI moderna y consistente. Una de sus principa-les ventajas es la multiplataforma. El ahorro delneas de programacin es muy significativo. Siadems le aadimos las ventajas que de por snos ofrece Python, encontramos en el binominoPython-wxPython una alternativa muy a teneren cuenta en el futuro de las aplicaciones.

    GNU/Linux es una plataforma ideal para eldesarrollo de aplicaciones con wxPython. En estecaso es importante el papel de las libreras deGTK+. Uniendo todos estos elementos consegui-mos un completo entorno de desarrollo en soft-

    ware libre.Quiz echamos en falta un completo IDE que

    nos permita disear de forma grfica la interfaz,

    as com editar cdigo, depurarlo, ejecutarlo, etc.Pues bien, por ahora podemos contar con Boa-

    Constructor, que es un IDE que pretender cubrireste hueco. De momento se encuentra en versinalpha, aunque podemos trabajar sin problemascon la ltima versin. Gracias a este IDE, escritoen Python, nuestro trabajo se simplificar ypodemos considerarlo como una verdaderaherramienta para el RAD (desarrollo rpido deaplicaciones).

    Muchos desarrolladores piensan quewxPython debe convertirse en el estndar paradesarrollar aplicaciones con interfaz grfica deusuario en Python. De hecho, algunos consideranque se trata de la forma ms rpida de migrar lasaplicaciones realizadas con MFC para que pue-dan ejecutarse en entornos UNIX y Mac OS.

    Linux55 MUNDO

    Interfaces grficas con wxPython

    Referencias

    q Proyecto wxWindows: http://www.wxwindows.orgq Proyecto wxPython: http://www.wxpython.orgq Lenguaje Python: http://www.python.orgqDescargas de wxPython: http://www.wxpython.org/dowloadqWiki site muy completo sobre wxPython: http://wiki.python.orgqGua de estilo para codificar en Python: http://www.python.org/peps/pep-0008.htmlq IDE para RAD en Python con wxPython: http://boa-constructor.sourceforge.netqOpen Source Initiative: http://www.opensource.org

    igidbc.py

    El autor ofrece el programa jgjdbc.py, escritoen Python, bajo licencia GPL, disponible en elrea de descargas de Mundo Linux, www.revistasprofesionales.com.Este programa genera un fichero XML con losdatos necesarios para utilizar un pool de cone-xiones de BD a travs de un Datasource en elservidor de aplicaciones JBoss. Lo crea para elSGBD que le indiquemos. Habitualmente hay

    que realizar esta tarea manualmente porqueno hay una herramienta que automatice elproceso.

    Figura 6.El site de wxPython.