Advertencia: Esta página esta basada (en parte) en opiniones y experiencias personales de distintas personas. YMMV

Existen varias librerías que implementan interfaces gráficas de usuario (GUI) en python, las principales son:

  • Tkinter: Basada en las librerías gráficas TCL/TK, interfaz "de-facto" (#1) preinstalada con python, es la generalmente recomendada para proyectos triviales y/o de aprendizaje.
  • WxPython: Basada en WxWidgets (una libreria multiplataforma C/C++), "bendecida" (#2) como la "más pitónica" por GvR (creador de Python), y sería la interface por defecto si no hubiese existido TK en primer lugar.
  • PyQT: basado en la libreria C++ QT (KDE)
  • PyGTK: basado en la libreria C GTK (GNOME)

Tabla comparativa

Caracteristica Tkinter WxPython PyQT PyGTK
Portabilidad Windows/Linux/Mac Windows, Linux (GTK+/X11/Motif), Mac OS X Windows, Linux, Mac OS X Windows, Linux, Mac OS X (via servidor de X)
Apariencia "alien" en todos nativa en todos nativa en linux y windows nativa en linux
Orientación/Influencias Motif Windows KDE GNOME
Diseñador "Visual" GUI Builder (Komodo) http://wxformbuilder.org|wxFormBuilder/wxGlade/XRCed QT Designer Glade, Gazpacho
IDEs Python IDLE SPE, BoaConstructor, DrPython Eric4 ??
Formato XML No sí (XRC incorporado) ?? sí (vía libglade antes, GTKBuilder ahora)
Otras facilidades ?? soporte para imagenes (BMP, PNG, JPG, etc.), visualización e impresión de HTML, clipboard y drag and drop, ayuda en linea, libreria de graficación de objetos ("vectoriales"), OpenGL, texto enriquecido (RTF) y "estilizado" (STC), programación en red, flujos, multitarea, bases de datos, unicode, gizmos varios, animaciones y multimedia hilos, control de procesos en segundo plano, renderización de svg, definición de aspectos estéticos de la GUI con CSS, personalización de la app en js, sockets, acceso a base de datos, pareso de XML, OpenGL Pango (texto multilingual), Cairo (gráficos 2D), ATK (accesibilidad)
Documentación Excelente Buena Regular Limitada
Ejemplos ?? Excelente (200 simples y 10 complejos) Bueno (20 simples y 20 complejos) ??
Licencia PSFL LGPL GPL (o http://www.pyside.org|PySide que es LGPL) LGPL

Características comunes

  • Tamaño aprox. (instalador windows desarrollo): 15MB (excepto tkinter que viene preinstalado)
  • Huella en memoria (footprint) de hello-word en windows: aproximadamente 20MB, excepto tkinter que es la mitad

Ventajas y Desventajas

Tkinter

  • Ventajas:
    • Preinstalado con python en casi todas las plataformas
    • Relativamente simple y fácil de aprender (recomendado para "aprendices")
    • Documentación completa
  • Desventajas:
    • Pocos elementos gráficos (sin listados, arboles, etc.)
    • Limitado control del comportamiento de la interface (recomendado para proyectos "triviales")
    • Lento (dibuja cada botón, etiqueta, menú, etc.) **
    • Apariencia "extraña" (no se parece a las aplicaciones nativas) **

Nota **: cabe aclarar que las ultimas versiones de TCL/TK mejoran varios de estos puntos, dibujando con las funciones nativas de la plataforma, lo que acelera y mejora la apariencia.

WxPython

  • Ventajas:
    • Completo conjunto de elementos gráficos (listados, arboles, grillas, etc.)
    • Flexible control del comportamiento de la interface
    • Rápido y de Apariencia nativa (diseñado para utilizar funciones nativas de cada plataforma)
    • "Baterias Incluidas": más de 12 librerias y utilitarios complementarios (ver comparación)
    • Independencia: no esta orientado a ningún entorno, ni QT ni GTK, hay una capa mas que agrega un grado de libertad adicional
    • No se cierra en el mínimo denominador común; soporta las características comunes de Windows, y las emula en Linux/Mac OS cuando no se pueden hacer nativamente (y viceversa).
    • Es mas "pitónico", por ej. espacio de nombres mas claro, sin referencias a C/C++, etc.
    • Permite separar completamente el diseño de la interface en XML del código python (XRC)
    • Es fácil armar componentes personalizados, tanto que incorpora widgets que no están en wxWidgets mismo, ya que están escritos en Python (AGW).
    • Documentación completa y ejemplos extensivos.
    • Su lista oficial de usuarios (wxpython-users) es muy activa y amigable, donde participan los desarrolladores principales del proyecto.
  • Desventajas:
    • No viene preinstalado con python, se debe instalar un paquete (wxPython en Windows y Mac OS, wxWidgets+wxPython en Linux, aunque en este último caso está generalmente está fácilmente disponible en los repositorios).
    • Relativamente mas complejo de aprender
    • Al tener un desarrollo bastante rápido y sostenido, se liberan versiones frecuentemente, lo que en la práctica le confiere cierto nivel de "volatilidad" y problemas de compatibilidad si se deben mantener varias versiones de wx para el mismo código.
    • Es una capa más sobre el toolkit gráfico que se usa debajo (ej: GTK).
    • Las características emuladas de otras plataformas no siempre se ven bien.
    • Hacer interfaces multiplataformas que se vean bien requiere conocimiento del toolkit subyacente (win32, gtk).
    • En proyectos medianos/grandes, puede ser inestable y dificil de debuggear: en windows es muy facil segfaultear si se pasan parámetros incorrectos.

PyQt

  • Ventajas:
    • Completo conjunto de elementos gráficos (listados, arboles, grillas, etc.)
    • Flexible y potente control del comportamiento de la interface. Posee un mecanismo de conexión de señales y eventos simple. Se puede definir los eventos más sencillos en diseñaodr de GUI's (ej: al pulsar este botón, borrar este campo de texto) y en el código python, definir las acciones más avanzadas.
    • Rápido y de Apariencia nativa (las últimas versiones utilizan funciones nativas en windows)
    • Se puede separar el diseño de la interface, pero usa un "compilador" pyuic para crear las clases python.
    • Arquitectura opcional para Modelo/Vista para las tablas, listas y árboles.
  • Desventajas:
    • No viene preinstalado con python, se debe instalar por separado
    • Relativamente mas complejo de aprender
    • No del todo "pitónico". En ocasiones emerge la implentación en C++ subyacente, teniendo que hacer casts entre tipos de datos, etc. El prefijo Qt/Q (QtGUI, QWidget, QAplicattion) hace el código menos "pitónico"
    • No hay mucha documentación específica a python, ya que es lenguaje en si no es demasiado considerado

PyGTK

  • Ventajas:
    • Completo conjunto de elementos gráficos (listados, arboles, grillas, etc.)
    • Flexible y potente control del comportamiento de la interface
    • Enlace con PyOrbit para programar aplicaciones en GNOME
    • Es estable, y los mensajes de error son correctos.
  • Desventajas:
    • No viene preinstalado con python, se debe instalar por separado
    • Relativamente mas complejo de aprender
    • Relativamente lento en Windows (dibuja cada botón, etiqueta, menú, etc.) lo que le da una Apariecia "extraña" (aunque es parecido a windows)
    • En windows, es la librería que tiene mas dependencias y se instalan por separado.
    • Aparentemente tiene la documentación mas precaria de todos

Hello World

Nota: para poder comparar, los ejemplos crean una aplicación, ventana y botón, con un evento.

Hay mas ejemplos en el recetario

TkInter

from Tkinter import *

class App:
    def __init__(self, master):
        frame = Frame(master)
        frame.pack()
        self.hi_there = Button(frame, text="Hola", command=self.say_hi)
        self.hi_there.pack(side=LEFT)
    def say_hi(self):
        print "hola todo el mundo!"

root = Tk()
app = App(root)
root.mainloop()

WxPython

import wx
class MyFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title )
        btn = wx.Button(self, -1, "Hola")
        self.Bind(wx.EVT_BUTTON, self.say_hello, btn)

    def say_hello(self,*arg):
        print "hola todo el mundo!"

class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, "Simple wxPython App")
        frame.Show(True)
        return True
MyApp().MainLoop()

PyQt

from PyQt4 import QtCore, QtGui
import sys

class MiVentana(QtGui.QWidget):
    def __init__(self, padre = None):
        super(MiVentana, self).__init__(padre)
        self.button = QtGui.QPushButton("Hola",self)
        self.connect(self.button, QtCore.SIGNAL("clicked()"), self.say_hello)
        self.show()
    def say_hello(self,**kwargs):
        print "hola mundo!"

app = QtGui.QApplication(sys.argv)
v = MiVentana()
app.exec_()

PyGTK

import pygtk
pygtk.require('2.0')
import gtk

class HelloWorld:
    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.button = gtk.Button("Hello World")
        self.button.connect("clicked", self.say_hello, None)
        self.window.add(self.button)
        self.button.show()
        self.window.show()

    def main(self):
        gtk.main()

    def say_hello(self, widget, data=None):
        print "Hello World"


hello = HelloWorld()
hello.main()

(sin testear)