Crear una aplicación gráfica en 20 minutos
Objetivo
1. Funcional
El objetivo de este capítulo es crear una aplicación que acceda a los mismos datos a los que se accede mediante la aplicación web y la aplicación de consola utilizando el mismo modelo y la misma configuración.
La interfaz gráfica propuesta es similar a la interfaz web, aunque ofrece una experiencia de usuario distinta, dado que los diseños de una interfaz web y una interfaz gráfica no responden a las mismas reglas ni exigencias.
2. Técnico
El principal logro de una aplicación gráfica es permitir un diálogo eficaz entre las acciones del usuario que hace clic en los elementos gráficos o informa datos y la manipulación efectiva y persistente de estos.
El diseño de una interfaz gráfica consiste en crear elementos gráficos tales como zonas de texto de información, zonas para introducir datos más o menos similares a los que se pueden introducir mediante HTML. La diferencia es que el vínculo entre el formulario y la aplicación se realiza mediante llamadas de retorno (callbacks) y no mediante peticiones.
La librería TkInter forma parte del núcleo de Python, y no es una librería externa que debemos agregar. Se ha adaptado para Python 3 (https://docs.python.org/3/howto/pyporting.html) y está completamente migrada.
Es una librería excelente, aunque no es la única que vamos a usar...
Breve presentación de Gtk y algunos trucos
1. Presentación
Gtk es una librería gráfica asociada al entorno gráfico Gnome. Forma parte del proyecto Gimp: sus creadores pensaron que era una lástima haber creado tantos componentes sin ofrecer la oportunidad a los demás de utilizar su formidable trabajo para crear otras aplicaciones.
PyGTK es una librería gráfica de libre distribución que conecta GTK+ a Python 2. Para Python 3, se trata de gi.repository. Esta última está escrita en C (utiliza Cairo) y forma parte de un conjunto mucho más amplio. Se utiliza en numerosas aplicaciones de referencia, como Gimp, por ejemplo, que está en el germen de entornos de escritorio como Gnome y Xfce. Está vinculada a la Libglade y a una aplicación de creación de interfaces gráficas Glade que es muy práctica y eficaz.
La librería GTK+ ha sido objeto de profundos cambios que han dado como resultado la aparición de GTK3+ (con rupturas de la compatibilidad hacia atrás perfectamente comprensibles) y en Python 3 disponemos únicamente de esta nueva rama.
Es importante destacar la existencia de una documentación de referencia indispensable que permite arrancar progresivamente, paso a paso, y que le aconsejo revisar antes o después de leer este capítulo: http://readthedocs.org/docs/python-gtk-3-tutorial/en/latest/index.html
En efecto, el ejemplo que explicamos aquí complementa esta documentación, presentando otros aspectos.
Los dos puntos importantes abordados aquí son la separación...
Iniciar el programa
Como hemos visto anteriormente, es preciso crear un nuevo punto de entrada para arrancar nuestro programa, en el archivo pyproject.toml:
[tool.poetry.plugins."console_scripts"]
initialize_project_db = "project.scripts.initialize_db:main"
show_settings = "project.scripts.settings:main"
contact = "project.scripts.contact:main"
gcontact = contact.scripts.gtk:main
Para conservar la compatibilidad con el sistema antiguo, también se puede modificar el archivo setup.py:
setup(name='contact',
version='0.0',
description='contact',
[...],
install_requires=requires,
entry_points="""\
[paste.app_factory]
main = contact:main
[console_scripts]
initialize_contact_db = contact.scripts.initializedb:main
show_settings = contact.scripts.settings:main
contact = contact.scripts.contact:main gcontact = contact.scripts.gtk:main
""",
)
Ahora hay que volver a desplegar la aplicación:
$ poetry build
$ poetry add ./project
A continuación hay que crear un archivo gtk.py en la carpeta scripts, donde ya podemos agregar código:
#!/usr/bin/python3
import argparse
from pyramid.paster import bootstrap
from sqlalchemy...
Interfaz gráfica con Glade
Cuando se trabaja con GTK, la adopción de una herramienta potente como Glade supone un verdadero ahorro de tiempo. Por otro lado, el resultado producido puede utilizarse tanto en Python como en C.
En este ejemplo, se ha diseñado una ventana, llamada main_window, que contiene una malla de dos columnas y cuatro líneas. Las tres primeras líneas de la primera columna contienen etiquetas.
Puede observar que el nombre asignado a cada uno de los componentes es importante y puede modificarse.
En la segunda columna, se ha agregado, sucesivamente, un campo de entrada (Entry), una lista de selección (ComboBox), una zona de texto (TextView) y, por último, un cuadro que contiene dos espacios que colocaremos de manera horizontal para agregar dos botones.
Interfaz general de Glade y eventos en la ventana
Como puede comprobar, la interfaz no es, necesariamente, agradable a la vista. Pero lo que importa son los parámetros que encontrará en las distintas pestañas del panel situado abajo a la derecha.
Puede hacer que los distintos elementos de la malla tengan la misma longitud o no, que estén centrados, alineados en la parte superior derecha…
Todavía más importante, puede seleccionar los callback que desea vincular a los eventos particulares. En la ventana principal, el evento importante es el clic en la cruz que permite salir de la aplicación. Aquí, se asocia...
Crear el componente gráfico
El componente gráfico dispone de tres métodos: un método de inicialización y dos métodos de callback, es decir, el método para salir de la aplicación cuando se hace clic en la cruz o en el botón de anulación, y el método de validación que creará un contacto.
He aquí la clase, con las correspondientes explicaciones para cada etapa:
class GtkContact:
def __init__(self, controller):
self.controller = controller
Empezamos agregando el controlador a la instancia en curso, lo que dará acceso a los métodos útiles que permiten recuperar los asuntos o crear el contacto. A continuación, es preciso cargar la interfaz que acabamos de diseñar con Glade:
interface = Gtk.Builder()
interface.add_from_file('contact/templates/contact.glade')
Nos contentamos con crear el builder y cargar el archivo Glade. A continuación, hay que recuperar punteros hacia los campos útiles, tarea que podemos realizar porque se han nombrado correctamente en Glade:
# Vínculos hacia los campos útiles
self.email = interface.get_object("email_entry")
self.subject = interface.get_object("subject_id_combobox")
self.text = interface.get_object("message_textview")
Ahora, es posible atacar al encargado...
Controlador
La interfaz tiene como objetivo permitir al usuario introducir un contacto. Debe, también, proveer la lista de asuntos, de modo que pueda recuperarse a partir de una lista de selección. Se trata de las dos únicas acciones que esperamos por parte del controlador. Es también el encargado de generar la interfaz gráfica y ejecutar el bucle de eventos.
He aquí el controlador:
class Controller:
def __init__(self, DBSession):
self.DBSession = DBSession
GtkContact(self)
Gtk.main()
def get_subjects(self):
return DBSession.query(Subject).all()
def add_contact(self, email, subject_id, text):
with transaction.manager:
DBSession.add(Contact(email=email, subject_id=subject_id,
text=text))
Tras la llamada a Gtk.main, el programa se pone en pausa y a la escucha de eventos generados por el usuario. Cuando se sale de la aplicación, invocando a Gtk.main_quit, el bucle termina.
He aquí el resultado:
Aplicación gráfica con el log de SQLAlchemy de fondo
Otras librerías gráficas
1. TkInter
TkInter es la librería gráfica utilizada por Python y es una migración de la librería gráfica de Tk creada para el lenguaje TLC.
Como gran ventaja cabe destacar que es fácil de implementar y se parece bastante a Gtk en su enfoque general.
2. wxPython
La librería wxPython es una librería que conecta los wxWidgets a Python. Es una alternativa a TkInter muy valorada y particularmente completa, próxima al sistema operativo.
La librería wxWidgets es una librería gráfica de libre distribución escrita en C++ que permite escribir una interfaz gráfica que será idéntica sea cual sea el sistema operativo, pero tomando su apariencia.
Esta librería es una referencia, y funciona en Python 3 a partir de la versión 3.3.
3. PyQt
PyQt es una librería gráfica de libre distribución que conecta Qt a Python. Qt, que debe pronunciarse como la palabra inglesa «cute», se escribe en C++ y es muy portable. El entorno gráfico KDE está construido en Qt. Muchos módulos complementarios adicionales hacen de ella mucho más que una simple librería que permite realizar interfaces gráficas.
Qt está vinculada a QtDesigner, que es, de manera similar a Glade, una aplicación que permite crear interfaces gráficas.
Qt está completamente migrada...