|
Pythonlópes - El Python que yo sé Parte IV: Algo de color al asunto
No es lo mismo tener la mente abierta
|
|
Es el colmo de la no linealidad: que el programa funcione sólo cuando pasa algo. A esto parece ser que se le llama evento, y aunque cueste más programar de esta forma, el resultado es mucho más llamativo y fácil de utilizar. Por eso es el sistema que se usa con entornos gráficos: yo pulso un botón y el sistema llama a una función. Al contrario de la programación tradicional, que nos obligaría a llenar el programa de 'ifs' y llamadas a funciones, no nos tenemos que preocupar más que de definir estas, y dejar que el intérprete las ejecute cuando hagan falta.
Claro está que para pasar a este "modo de actuar", hemos de decírselo. Para eso está la función Register, que, ¡oh, casualidad!, viene en el nódulo Draw, que sirve para diseñar deliciosas interfaces. El intérprete la pondrá a trabajar y estará durante todo el tiempo funcionando, de manera que todo correrá de esta forma tan particular. El mecanismo es sencillo: Register empieza a funcionar cuando la llamamos (generalmente es la única función que hay en el programa principal, todo lo demás está "subordinado"). Register tiene 3 parámetros, que son otras 3 funciones, entre las que saltará dependiendo del estado de los eventos. Podemos llamarlas así (entre paréntesis va el nombre que tradicionalmente se les da): Blender.Draw.Register (Draw , event , bevent)*Función de dibujo (Draw): Aquí definimos variables, que previamente habrán sido declaradas globalmente mediante variable=Create(valor) (lo veremos después). Cada variable de estas definirá botones y cajas que, al ser activadas por el usuario, pueden generar eventos. No tiene argumentos. *Función de eventos de pulsación (event): Es la función receptora de eventos de teclado y ratón, que tiene dos argumentos: la variable que contiene el número de evento, y la otra, que vale 0 cuando se suelta la tecla/ratón, y otro valor mientras se mantiene pulsada (ver dir(Blender.Draw) para investigar). Para teclas especiales y movimiento de ratón recibe otros valores también. *Función de eventos de botones (bevent): La que ejercerá el mayor control del programa y donde se hará más gordo. Aquí se toman las decisiones sobre botones y controles pulsados sobre el interface. Es análoga a la anterior.
Un poco largo para no hacer nada, ¿no? Podemos distinguir aquí varios niveles de ejecución: en primer término se ejecuta Register y NADA MÁS. Register llama primero a dibuja, que borra la pantalla con instrucciones OpenGL y escribe un mensaje (Text está en Draw, no en BGL) En este estado, espera a que suceda algo, bien desde el teclado o ratón, o se pulse un botón (en este caso no hay). Aquí el único evento que tiene efecto es la pulsación de la tecla ESC, que, UNA VEZ LIBERADA (notar el not val) produce la salida de la función y, por tanto del programa. Nota: Register se ejecuta siempre al final del programa, o sea, aunque escribamos líneas debajo, se harán antes. |
|
Y no es el del ombligo.
La documentación del módulo Draw es imprescindible para seguir. Vemos que hay instrucciones que crean cosas que generan eventos, otras que no (Text), unas devuelven valores (Menu, Number...), y otras no lo necesitaremos (Button), y todas tienen un formato similar en tanto todas dibujan algo en la ventana, esperan un evento y manejan valores. Vamos a dibujar un botón. Para ello, escribimos al final de la función dibujo:
Button("Hacerlo!",0,30,20,80,30,"Venga ya!")
Y al ejecutar el script con Alt+P veremos un botón precioso, que incluso nos escribe un tip si dejamos el ratón sobre él.
El primer número es (será en todos los casos) el evento que mandamos a Register, y cuando pulsemos el botón se hará una llamada a bevent con el valor del evento. Pero esto sólo sucederá si este número no es 0 como ahora, así que podemos sustituir este 0 por 1, y sustituir el pass por: if event==1: print '¡BUENA PUNTERIA!'Ahora, más que nunca, conviene tener a nuestro Blender no maximizado, ocupando sólo una parte de la pantalla, y poder así ver al mismo tiempo la consola de texto (donde aparecen además los Prints). Cuando ejecutamos el script y pinchamos en el botón, aparece el mensaje en la consola. Bien. Ahora debería estar claro el funcionamiento general del asunto, así que vamos con lo que Blender nos pide a cambio para darnos este lujo de entorno. |
|
Vamos a hacer un programa que lo contemple todo. En dibuja definimos todos los tipos de botones y texto, usamos la interesante función GetStringWidth para obtener la longitud en pixels de un texto, y definimos eventos para mandar.
En event aprendemos a usar los eventos de teclado, y en bevent vemos lo fácil que es decidir qué hacemos con los eventos de botón, y cómo obtener los valores que los botones nos devuelven.
Notas: * IMPORTANTE - Sobre las variables: Como se puede ver, las variables que devuelve un botón no son variables comunes. En realidad, una variable como intns o numero es, en realidad un PyObjeto, digamos, de clase "botón". El valor real que devuelve este objeto está almacenado en el atributo objeto.val, en todos los casos. * Y como tales objetos, hay que declararlos antes, en este caso mediante la función Create(valor_por_defecto) (1). Una vez las vayamos a usar, como en la función dibuja, hay que llamarlas como globales como en (2). * Slider tiene un parámetro (el penúltimo, anterior al tip, y opcional, y que aquí hemos puesto 0) que, de no ser 0, permite mandar eventos mientras cambiamos el valor. Esto lo hace muy lento, pero conseguimos efectos en tiempo real. * En la declaración de los botones, para aquellos que almacenan un valor, hay un parámetro que es el valor de la propia variable, por ejemplo:
numero=Number("Cuantas veces:",4,20,150,120,18,numero.val,0,1000)
^^^^^^^^^^
Este será el valor que marcará el botón cada vez que se redibuje, lo que en condiciones normales será su mismo valor, como es lógico. Pero podemos hacer que este valor sea el que marca otro botón, o bien el resultado de una operación, o lo que nuestra imaginación alcance.
* Notar, en la función event, la diferencia entre aceptar el valor y el no-valor. Cada decisión se acepta como positiva, pero en el caso de la tecla 'A' se hace cuando se pulsa, y en el de 'ESC' cuando se suelta. |
|
V.24,11,3 - © 2003 Carlos López Escríbeme y dime algo... ¡tú puedes hacerlo! Gracias a todos los reporteros de fallos que hacen que esto se vaya corrigiendo ;-) |