Tutoriales básicos: Mi primer GUI, mi primer botón

Antes de ir al Soporte consultame aquí, gracias
Responder
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Tutoriales básicos: Mi primer GUI, mi primer botón

Mensaje por Ximorro »

TUTORIAL: Mi primer GUI, mi primer botón
Versión: 1.1
Autor: Ximorro
Objetivo: mostrar cómo insertar un botón en un GUI y hacerlo interactivo con el usuario.
Dificultad: MUY básico.
Conceptos clave: GUI, botón, evento.

Veo que algunos foreros tienen dificultades para manejar controles en los formularios o ventanas, también llamados ampliamente GUI, aunque esa palabra esté formada por siglas que vienen del inglés.

Para las cuestiones básicas se recomienda encarecidamente consultar en la ayuda oficial que viene con el programa, pues para estos casos es más que suficiente. Si no entendéis la ayuda en inglés en este foro encontraréis un enlace a la traducción española, el último a fecha de escritura de este tutorial es este:
http://www.emesn.com/autoitforum/viewto ... f=2&t=1903

En cualquier caso voy a exponer un ejemplo muy simple que explicaré con mayor detalle de lo que se puede encontrar en la ayuda, a ver si así afianzamos algunos conceptos y con estas ideas claras podemos avanzar más rápidamente y con paso firme cuando creemos GUIs más complejos. Y es que sin saber lo que se está haciendo es un poco complicado crear GUIs en particular o programar en general... :smt002

Analicemos pues este sencillo ejemplo que simplemente crea un botón que minimiza el formulario al ser pulsado.

Código: Seleccionar todo

#include <GUIConstantsEx.au3>

GUICreate("Gui de un botón", 200, 100)
$btnMini = GUICtrlCreateButton("&Minimizar", 60,30, 80,30)
GUISetState(@SW_SHOW)

While 1
	Switch GUIGetMsg()
		Case $btnMini
			GUISetState(@SW_MINIMIZE)
		Case $GUI_EVENT_CLOSE
			ExitLoop
	EndSwitch
WEnd
Atención: en este tutorial se supone que ya se entiende cómo funcionan las estructuras de control tipo While o Switch, aquí nos centraremos en la creación del GUI y cómo interactuar con él. Para aprender sobre las estructuras de control mirad la ayuda, si yo lo explicara prácticamente no haría más que repetir lo que pone allí, así que es innecesario que lo haga (pero si no sabéis que es eso de un While o un Switch ya estáis mirándolo, este tutorial aún es un poco avanzado para vosotros).

Antes de entrar en detalle en el programa hablemos de qué es un evento, pues este es un concepto relacionado con GUIs y que manejaremos y veremos mucho por el foro (y otros muchos sitios):
.- Un evento (en nuestro caso) es una indicación de que algo ha ocurrido en nuestro GUI, casi siempre referido a una interacción del usuario, aunque algunos pueden ser lanzados por el sistema. Por ejemplo se disparará un evento cuando se cliquee un botón, cuando se pulse el aspa de cerrar que hay en la barra de título del formulario, etc... Hay que hacer notar que AutoIt tiene un sistema más bien sencillo de eventos, no notifica absolutamente todo y para hacer cosas más complejas habrá que usar mecanismos diferentes a los aquí descritos. Pero no os asustéis, con el sistema básico de eventos se pueden hacer GUIs muy complejos.
.- AutoIt tiene dos modos para manejar eventos, modo MessageLoop y modo OnEvent.
.- Modo MessageLoop, es decir, modo de bucle de mensajes, es probablemente el más usado. En este modo AutoIt nos manda mensajes indicando que se han disparado eventos, nosotros tenemos que preguntar expresamente si ha llegado algún mensaje de evento, si ha llegado se procesa, si no pues seguimos comprobando hasta que llegue uno. Este es el modo usado en este ejemplo.
.- modo OnEvent, o modo EnEvento..., en este modo cuando se activa un evento el programa es interrumpido esté donde esté e inmediatamente se ejecuta la función que hayamos creado para manejar el evento, cuando dicha función finaliza el programa es reanudado allá donde estuviera trabajando. Este modo está fuera del alcance de este tutorial.

Veamos cómo se usa el modo de bucle de mensajes para manejar nuestro pequeño GUI:
La primera línea del programa es una directiva #include, esto añade una librería a nuestro programa que incluye funciones y/o constantes o variables predefinidas, en nuestro caso incluimos GUIConstantsEx.au3 porque es donde está definido, entre otros, el mensaje $GUI_EVENT_CLOSE, que nos notificará cuando se produzca un evento de clausura del formulario.

A continuación se crea la ventana del formulario con GUICreate, donde indicamos el título y el tamaño (se pueden añadir otras cosas, como posición o estilo).

Después de crear la ventana (el GUI), creamos los controles que van en ella (botones, etiquetas, cajas de texto, etc.). En este caso creamos sólo un botón con GUICtrlCreateButton. Fijáos en la asignación a la variable $btnMini, esto lo hacemos para referenciar el botón posteriormente. Asignar los controles a variables es opcional, depende de lo que vayamos a hacer después con ellos, por ejemplo una etiqueta que vaya a quedar estática la crearemos y la dejaremos fija para siempre, con lo que no será necesario referenciarla. Por cierto, el GUI también podríamos asignarlo a una variable, si nos hiciera falta.

He puesto una cosita de regalo, ese "&" antes de la M en "&Minimizar" indica que esa letra estará subrayada en el botón del GUI, con lo que al presionar ALT-M cuando la ventana esté activa será como pinchar el botón con el ratón (dicho de otra manera, es otra forma de lanzar el evento de cliqueo del botón)

Una vez creados todos los controles ya podemos mostrar el formulario, que está oculto mientras lo estamos construyendo. Esto se hace con GUISetState(@SW_SHOW), en realidad @SW_SHOW es el valor por defecto de esta función, esto quiere decir que lo podemos omitir, GUISetState() hará exactamente lo mismo.

Ahora empieza el bucle principal de gestión de eventos. Típicamente lo que se hace es crear un bucle infinito que comprueba si han llegado mensajes de evento. Sí, infinito, pero AutoIt, y nosotros los programadores, ¡somos tan poderosos que podemos escapar del infinito! Y si no escapamos del infinito es que estamos haciendo algo realmente mal. La verdad es que como veréis es bien fácil, pero eso que quede entre nosotros :smt003

Un bucle infinito se hace con una condición de parada... que no pare nunca. Por ejemplo con un "mientras" podemos hacer:

Código: Seleccionar todo

While true
	;bloque de instrucciones a repetir
WEnd
Como la tarea se realiza "mientras verdadero", y true siempre va a ser verdadero, siempre repetirá el bucle. En realidad cualquier valor o expresión que dé como resultado un valor distinto de false, cero (entero o real) o cadena vacía ("") se considera cierta, así que una variante muy utilizada en AutoIt es usar un 1 como equivalente a true. Como se usa muchísimo así lo he puesto en el ejemplo, lo veréis continuamente en los ejemplos.

Dentro de este bucle "sin fin" lo que hacemos es comprobar continuamente si llega algún mensaje notificando un evento, de aquí el nombre de modo de bucle de mensajes. Preguntamos a AutoIt si ha llegado un mensaje con GUIGetMsg(). Esta función devuelve un valor predefinido para algunos eventos del sistema (como cuando el formulario es cerrado, cambiado de tamaño, maximizado, etc.) así como notificaciones de eventos sobre nuestros controles, por ejemplo cuando el usuario hace clic sobre un botón. En este caso en vez de devolver un valor predefinido lo que hace es decirnos qué control está implicado (por lo que sólo muestra un tipo de evento por control, esta es la limitación de la gestión de eventos de AutoIt que os comentaba cuando explicaba qué es un evento).

El Switch es una forma conveniente de hacer una cosa u otra dependiendo del mensaje que nos llegue, naturalmente se podría hacer lo mismo con una cascada de If-Then-ElseIf..., o con Select, por ejemplo.
Así que si ha llegado un evento proveniente del botón (Case $btnMini) ejecutamos lo que queremos que haga dicho botón, en este caso minimizamos el formulario. Esto se hace con la misma función que usábamos para mostrarlo, pues esta función cambia el estado del GUI según el parámetro que le demos (mostrado, oculto, maximizado, minimizado, etc.). Lo minimizamos con el valor correspondiente para este estado: @SW_MINIMIZE.
Como veis aquí es donde nos es útil haber guardado el botón en la variable $btnMini. Si no lo hubiéramos hecho igual nos notificaría el mensaje cuando se pulsara el botón, ¡pero no podríamos saber que se trata de nuestro botón!.

El siguiente evento que comprobamos es cuando el usuario quiere cerrar el GUI, algo que sólo puede hacer pulsando en el aspa de la barra de título, pues no le hemos puesto un botón de "Cerrar" o similar (vale, también lo puede cerrar con ALT-F4 y también otros métodos menos conocidos, como ESC ;-) ). La verdad es que este tipo de eventos puede ser lanzado también por el sistema, por ejemplo si finalizas la aplicación desde el Administrador de Tareas de Windows (pero no si terminas el proceso abruptamente, en vez de finalizar la aplicación).
En ese caso GUIGetMsg() nos devuelve $GUI_EVENT_CLOSE. Cuando esto ocurra lo que hacemos es... ¡salir del bucle infinito!. Esto se hace simplemente con ExitLoop, que sirve precisamente para finalizar al momento el bucle en curso, sea éste infinito o no. En este caso como el programa no tiene más instrucciones para ejecutar después del bucle, simplemente finalizará, que es lo que queremos. En este caso tan simple en vez de salir del bucle también podríamos hacer que finalice directamente el programa con Exit.

IMPORTANTE: Que nos notifiquen el evento no siempre quiere decir que se haya realizado la tarea que le corresponda, precisamente la notificación es para que hagamos dicha tarea, si queremos, ¡ese es nuestro trabajo!.
Es decir, que nos diga que el usuario ha pulsado nuestro "botón de minimizar" no minimiza el formulario, el sistema nos informa de que se ha pulsado ese botón ¡y entonces es nuestro trabajo actuar en consecuencia y minimizar el formulario!
Esto no siempre es tan evidente, si quitamos las dos líneas:

Código: Seleccionar todo

Case $GUI_EVENT_CLOSE
   ExitLoop
¡el formulario NO SE CERRARÁ!, GUIGetMsg() sí que nos estará diciendo que se está intentando cerrar el formulario, pero no le estamos diciendo lo que tiene que hacer cuando llegue ese mensaje, somos nosotros los que tenemos que poner las instrucciones que realmente cierren el GUI. Este mecanismo es el que permite por ejemplo que un editor de texto te pregunte si quieres guardar el documento en edición cuando le has dado a cerrar. ¡Si Windows cerrara directamente el programa no tendría tiempo de preguntar y se perdería el documento!

¡NORMALMENTE EL SISTEMA NOS NOTIFICA LOS EVENTOS, NOSOTROS DEBEMOS RESPONDER A ESOS EVENTOS!

Por conveniencia hay una excepción a esto, aunque es opcional (por defecto está activado), y es que los eventos del sistema de maximizar ($GUI_EVENT_MAXIMIZE), minimizar ($GUI_EVENT_MINIMIZE) y restaurar ($GUI_EVENT_RESTORE) sí son procesados por el sistema. Pero ojo, sólo los eventos del sistema Windows estándar, como los botoncitos de la barra de título, no los de nuestros controles propios como el botón de minimizar de nuestro ejemplo.
Este comportamiento se puede desactivar poniendo la opción GUIEventOptions a uno, (por defecto está a cero):

Código: Seleccionar todo

Opt("GUIEventOptions", 1)
En este caso estos tres eventos especiales no serán procesados, sólo notificados.

Bien, aquí finaliza este mini-tutorial, espero que os sea útil. No os podéis quejar de lo extensamente explicado que está algo más o menos sencillo, pero como es la base de la gestión de eventos en AutoIt, al menos en el modo MessageLoop, he creído interesante desarrollarlo bastante.

¡Espero que os aproveche!
Ximorro


-----------------
Versión 1.1, 5/08/2010
.- Incluida información sobre GUIEventOptions y el tratamiento especial de los eventos del sistema de minimizar, maximizar y restaurar.

Versión 1.0, 4/08/2010
.- Versión inicial.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
BasicOs
Site Admin
Mensajes: 2083
Registrado: 21 Nov 2006, 19:24
Ubicación: El Internet - (Canarias, España)
Contactar:

Re: Tutoriales básicos: Mi primer GUI, mi primer botón

Mensaje por BasicOs »

Muy bueno el tutorial, Gracias por la información,
Salu22) :smt023 :smt023 :smt038 :smt038
Andres_sc
Aprendiz de Mago
Mensajes: 59
Registrado: 16 Jul 2010, 23:54

Re: Tutoriales básicos: Mi primer GUI, mi primer botón

Mensaje por Andres_sc »

Muy buen tutorial, gracias me sirvio de mucho para aclarar una cuantas dudas
sobre todo por mi escaso ingles y por que soy nuevo en autoit.
se te agradece la info :smt023 :smt038
Espero que sigas con tutoriales basicos para gente como yo que todavia
les cuesta conocer todas las funciones basicas de autoit. :smt017
saludoss !!
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Tutoriales básicos: Mi primer GUI, mi primer botón

Mensaje por Chefito »

Muy buen tutorial para empezar :smt038 . Seguro que a más de uno le sirve.

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Tutoriales básicos: Mi primer GUI, mi primer botón

Mensaje por Ximorro »

Gracias a todos, a los profesionales porque os guste algo que para vosotros es "una tontería" (por cierto, que si queréis hacer enmiendas o ampliaciones sólo tenéis que decirlo) y a los que estáis empezando porque el objetivo es que os sea útil, si os ha gustado es que sí se está cumpliendo ese objetivo ¡por vosotros lo he hecho!

Andrés, espero que ahora puedas mejorar tu GUI del otro post ;-) y que pronto puedas aportar a la comunidad un montón de programas interesantes.
Por cierto, si no puedes con el inglés (y la verdad, es interesante saber un poco, que leer una ayuda de algo informático es mucho más fácil que leer una novela) pues te recomiendo mirarte la ayuda traducida por el equipo de novii. Tienes enlaces en este foro.

Respecto a seguir haciendo tutoriales pues bien, no tengo pensado ninguno pero es algo que por supuesto no descarto. La verdad es que es un esfuerzo considerable porque aunque sean temas básicos explicarlo con tanto detalle cuesta. Pero si veo otro tema en el que se cae recurrentemente en errores o si hay sugerencias puedo animarme. Si no dejamos las bases claras difícilmente se avanza.

¡Desde luego vuestros ánimos me predisponen a seguir en la línea!
Y vaya, que las puertas también quedan abiertas a los demás profesionales que veáis que respondéis a las mismas preguntas una y otra vez.

Ya veremos qué temas pueden ser interesantes de desarrollar, y también puede haber peticiones, claro.
Como problemas básicos también he visto que no se controla mucho las estructuras de control, pero la verdad es que creo que con la ayuda oficial sería suficiente para entenderlas, y volver a repetir casi lo mismo no sé si es tan útil...
Otros temas interesantes pueden ser las matrices o el modo OnEvent, pero no parece que tengan tantos problemas con las primeras o que usen mucho el segundo ;-)
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Tutoriales básicos: Mi primer GUI, mi primer botón

Mensaje por Ximorro »

He actualizado el tutorial con información sobre los eventos del sistema de minimizar, maximizar y restaurar, en realidad estos eventos sí los procesa Windows, aunque esta es una excepción y es un comportamiento configurable.

Cuando fui tan categórico con lo de que hay que procesar todos los eventos no era del todo correcto y llevaba a confusión. Una cosa es no contarlo todo para no salirse del objetivo de tutorial básico, otra cosa es confundir al personal... ;-)

También ha añadido un "historial" al final del documento.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Guybrush
Mensajes: 2
Registrado: 30 Ene 2013, 13:25

Re: Tutoriales básicos: Mi primer GUI, mi primer botón

Mensaje por Guybrush »

Gracias por ese tutorial básico, la verdad es que hasta ahora había estado trabajando sin usar la GUI, pero esto la verdad es que da bastantes posibilidades. Acaba de cambiar mi percepción del autoit, que lo veía como un generador de scripts, a verlo como un lenguaje de programación bastante completo.
Responder