3 de Agosto, 2013

Pyglet y programación orientada a objetos

Una de los puntos fuertes de Pyglet es que es muy sencillo empezar a trabajar porque la librería se encarga de gestionar muchas cosas por nosotros (realmente muchas comparado con PyGame), de forma que un hola mundo es tan sencillo como:

import pyglet

window = pyglet.window.Window()
label = pyglet.text.Label('Hello, world', 
                          font_name='Times New Roman', 
                          font_size=36,
                          x=window.width//2,
                          y=window.height//2,
                          anchor_x='center', 
                          anchor_y='center',
                          )

@window.event
def on_draw():
    window.clear()
    label.draw()

pyglet.app.run()

No tenemos que preocuparnos de gestionar el bucle principal de la aplicación, donde se procesan eventos como se pulsa una tecla o hay que dibujar, y con los decoradores que nos ofrece pyglet podemos designar qué funciones van a encargarse de qué eventos (en el ejemplo con on_draw).

Para empezar está bien, pero en mi experiencia esta estrategia tiende a escalar muy mal cuando nuestro proyecto empieza a crecer. Yo personalmente prefiero un enfoque más orientado a objetos creando una clase que herede del objeto Window, evitando así trabajar con variables globales.

# coding=utf-8
import pyglet

class Main(pyglet.window.Window):
    def __init__(self):
        # inicializa tu app para todo lo que afecte a la ventana cuando,
        # es creada; por ejemplo desactiva debug en OpenGL
        pyglet.options['debug_gl'] = False

        # aquí también podríamos usar un OptionParser para procesar opciones
        # como activar el modo debug

        # inicializamos la clase base (Window)
        super(Main, self).__init__()

        # aquí seguiríamos con la inicialización de nuestra app
        # independiente de la creación de la ventana

        # width y height tienen el valor asignado por el constructor de Window 
        self.label = pyglet.text.Label('Hello, world', 
                                       font_name='Times New Roman', 
                                       font_size=36,
                                       x=self.width//2,
                                       y=self.height//2,
                                       anchor_x='center',
                                       anchor_y='center',
                                       )

    def on_close(self):
        """Se va a cerrar la ventana"""
        # liberar recursos si hace falta

        super(Main, self).on_close()

    def on_draw(self):
        """Dibujamos la escena"""
        self.clear()

        self.label.draw()

if __name__ == "__main__":
    main = Main()
    pyglet.app.run()

Se puede ver como todos los eventos que definiríamos como un decorador tipo window.event ahora son métodos de la clase Main porque hereda de Window. Además la ventana es ahora el objeto así que usamos self para referirnos a ella dentro de los métodos de Main y evitamos usar variables globales (como cuando tomamos su ancho y alto para posicionar el texto).

Recomiendo echarle un ojo a la documentación de la clase Window, sobretodo para ver qué eventos soporta, pero básicamente la clase Window es perfecta para ser el centro de nuestra aplicación.

Estoy aprendiendo muchas cosas interesantes cacharreando con Pyglet y es una pena porque no hay casi documentación fuera de la web oficial del proyecto, así que a ver si saco tiempo y escribo más mini-artículos como este ;).

Anotación por Juan J. Martínez, clasificada en: pyglet, python, programming.

Los comentarios están cerrados: los comentarios se cierran automáticamente una vez pasados 30 días. Si quieres comentar algo acerca de la anotación, puedes hacerlo por e-mail.

Algunas anotaciones relacionadas: