Main logo La Página de DriverOp

Tutorial Delphi - La VCL nuestra de cada día.

Temas.

La biblioteca de componentes visuales.

Hasta ahora hemos visto más o menos cómo está organizada una aplicación Object Pascal y cómo administra esto el IDE de Delphi. Pero no es todo lo que hay para saber acerca de esta herramienta de programación. Quizás lo mejor de Delphi, el gran acierto de Borland al proporcionarnos esta herramienta sea la VCL. VCL son las iniciales en inglés de Visual Components Library, o sea, la Biblioteca de Componentes Visuales. Se trata de un conjunto de bibliotecas (units) donde están declarados todos los tipos, procedimientos y funciones estandar de Windows en lenguaje Object Pascal pero, además, contienen las especificaciones de los componentes más comunes de Windows tal como botones, cajas de listas, combos descolgables, etiquetas visuales y formularios (ventanas). Si bién esto último es muy útil la VCL tiene la propiedad de expandirse para adoptar nuevos componentes visuales hechos por terceros programadores y aquí es donde reside la utilidad final de la VCL. En Internet se encuentran cientos sino miles de componentes hechos especialmente para Delphi usando las herramientas de Delphi que pueden agregarse a la VCL de nuestra copia de Delphi y usarse como si fuera un componente más de los que ya trae Delphi "de fábrica".

Para comenzar a explorar la paleta de componentes VCL de Delphi crearemos un nuevo proyecto. Haciendo click en el menú "File", luego "New", luego "Application", guardaremos los cambios en el proyecto anterior si lo tenías abierto. Entonces tenemos un nuevo proyecto en blanco (el cual llamaré Project2) listo para ser completado por nosotros.

Los componentes más comunmente usados.

Veremos a continuación ocho componentes, siete de los cuales son visuales, esto quiere decir que el usuario de nuestra aplicación los podrá ver y usar, es decir, interactuar con él ya sea con el mouse o con el teclado o ambos, algunos de ellos solo sirven para presentar información visual. Y veremos un componente no visual el cual, como su nombre lo indica, no es visible para el usuario pero es útil para el programador ya que simplifica su tarea de alguna manera.

Primero taeremos al frente la paleta "Standard".

La paleta Standard

Fig. 1 - La paleta Standard.

Label (TLabel) Label (TLabel).

Este componente sirve principalmente para sobreimprimir texto estático no seleccionable por el usuario, es muy útil para indicarle cosas al usuario o para describir la función de otros componentes en nuesta aplicación. Selecciona este componente y suéltalo en el Diseñador de Formulario tal como hicimos con el Button en el capítulo 2 de este tutorial. Observa en el Inspector de Objetos todas sus propiedades, presiona F11 para traer la ventana Inspector de Objeto si no la tienes visible en el IDE.

La principal propiedad de este componente es Caption, en la cual puedes escribir el texto que aparecerá en el componente. Reemplaza la cadena "Label1" por "Ingrese texto", mientras lo haces ese texto se modifica automáticamente en el Diseñador de Formulario. Como hicimos con el Button en el capítulo dos puedes reubicar el Label en cualquier parte del formulario arrastrandolo con el mouse o bién modificando las propiedades Top y Left del mismo. También puedes redimensionarlo usando los pequeños cuadros negros que rodean el componente en el Diseñador de Formulario. Al hacer esto notarás un comportamiento extraño al principio. Estira el componente hacia la derecha y hacia abajo, luego vuelve a modificar la propiedad Caption usando el Inspector de Objetos, verás que el componente se redimensiona solo hasta encerrar el texto escrito, incluso si no pones ningún texto el componente se comprime hasta casi desaparecer. Esto se debe a que por omisión su propiedad AutoSize está en True (verdadero), modifica esa propiedad y ponla en False (falso), entonces sí podrás dejar el componente al tamaño que quieras. Otra propiedad interesante de este componente es Alignment (alineación) que se refiere a cómo el texto aparecerá, en el Inspector de Objeto verás en esta propiedad tres valores posibles: taCenter, significa que el texto estará centrado, taRightJustify, el texto se alineará a la derecha y taLeftJustify el texto lo hará a la izquierda.

Por lo pronto deja taRightJustify para la propiedad Alignment, escribe "Ingrese texto" en Caption y pon AutoSize en true.

Otras propiedades son evidentes (si sabes algo de inglés), por ejemplo Color (color), Font (fuente), Height (altura), Width (ancho), etc... pero hay una de especial interés que todos los componentes comparten sin distinción la cual es Name, si no la has modificado aún deberá ser para nuestro caso "Label1". La propiedad Name es el nombre con el cual nos referiremos en el código fuente del formulario (la unidad asociada) por eso es muy importante que una vez puesto el nombre lo mantengamos si no deseamos cambiar luego todas las referencias a ese componente en el código de nuestro programa. Por lo pronto lo dejaremos como está.

Edit (TEdit) Edit (TEdit).

Este componente sirve especialmente para que el usuario ingrese texto a nuestra aplicación y funciona como si fuera un editor de texto de una sola línea. Suelta un Edit en el formulario y colócalo justo a continuación del Label que ya tenemos allí. La propiedad principal del Edit es Text, que por omisión tiene la cadena de caracteres igual al nombre del componente, elimínalo para limpiar el texto que aparece en el componente en el Diseñador de Formulario. Si estudias el resto de las propiedades del Edit verás que comparte algunos con el componente Edit (¡pero no tiene Alignment!... se puede solucionar) y funcionan de la misma manera solo que aplicado a este componente.

Compila y ejecuta el programa tal como está ahora con F9 y experimenta cambiando las propiedades de ambos componentes. Algunas propiedades clave son:

Enabled: establece si el componente responde al usuario o a otros eventos.

Visible: el componente es visible al usuario.

Color: el color del componente, en el caso del TEdit es el color del fondo.

MaxLength: la cantidad máxima de caracteres que admite el componente, cero para infinito.

ReadOnly: el componete es de solo lectura. A diferencia de Enabled esta propiedad hace que el componente responda a los eventos excepto que su contenido no es modificable por el usuario.

TabStop/TabOrder: estas propiedades indican si el componente recibirá el foco cuando el usuario presione la tecla Tab y en qué orden lo hará con respecto al resto de los componentes con la misma capacidad de recibir el foco (Buttons, CheckBoxes, Memos, etc...)

Memo (TMemo) Memo (TMemo).

Este componente es un mini editor de texto donde el usuario puede escribir texto en varias líneas. Su principal propiedad es Lines el cual es un TStrings (hablaremos más tarde de esto). El texto puede ser ingresado tanto por el usuario como por el programador por medio de código.

Pasemos a la paleta de componentes "Additional":

La paleta

Fig. 2 - La paleta "Additional"

Esta paleta contiene más componetes comunes a Windows, de aquí describiré solo tres.

BitButton (TBitBtn) BitButton (TBitBtn).

Este componentes es casi identico al TButton visto en nuestro primer programa con la gran diferencia que permite que junto con el Caption se le pueda agregar una imágen como decorado o icono. Para ello se usa la propiedad Glyph, la imágen debe ser de tipo BMP y debe coincidir en tamaño con el botón.

Hay una particularidad con respecto a las imágenes insertadas en un BitButton. El pixel inferior izquierdo de la imágen se establece como el pixel transparente. Esto significa que si el pixel de la esquina inferior izquierda es negro todo lo que es negro en la imágen del Glyph se vuelve transparente. A tener en cuenta para lograr efectos interesantes. La propiedad Layout controla en qué lugar del BitButton estará la imágen (derecha, izquierda, arriba o abajo). Luego el BitButton es similar al Button en otros aspectos.

SpeedButton (TSpeedButton) SpeedButton (TSpeedButton).

Este es un button especial que acepta imágenes igual que el BitButton pero tiene un mayor control del mismo, es para hacer botones "artísticos", además de Layout el SpeedButton tiene otras propiedades para ajustar la imágen y el Caption (Spacing, si es que tiene) así como ajustar la distancia entre la imágen y el borde elegido con Layout, Margin, donde el valor -1 indica centrado, cero indica 0 pixels entre el borde y la imágen y así. También tiene otra propiedad interesante, Flat, con esta puedes hacer que el borde del SpeedButton desaparezca pero solo aparezca cuando el puntero del mouse pasa por encima de él, al estilo de los botones del Internet Explorer (este efecto es apreciable en tiempo de ejecusión, no en tiempo de diseño). Por último tienes la propiedad Down que hace que el botón permanezca hundido una vez se hace click en él, debes cambiar la propiedad GroupIndex a un valor distinto de cero para que esta propiedad tenga efecto.

Image (TImage) Image (TImage).

Este componente permite visualizar imágenes BMP, sirve tanto para decorar el formulario o como visualizador de este tipo de archivo (para ver imágenes JPEG debes agregar manualmente la unidad jpeg a la "uses" de la Units donde está el TImage) para ello se usa la propiedad Picture. Para estirar la imágen de forma tal que ocupe el misma ancho y alto del componente se usa la propiedad Stretch en True.

Por último vamos a ver un componente no visual en de la paleta "System":

La Paleta

Fig. 3 - La Paleta "System".

Timer (TTimer) Timer (TTimer).

El TTimer es un componente no visual, esto quiere decir que el usuario no lo ve cuando la aplicación se ejecuta, solo es visible al programador en tiempo de diseño por lo que no importa dónde lo coloques en el formulario, este no se verá. Su función es muy útil, se trata de un cronómetro que dispara un evento OnTimer cuando se vence un plazo de tiempo en milisegundos (1000=1 Segundo), propiedad Interval. Cuando su propiedad Enabled está en true se dispara el cronometro y cuando este es igual o mayor a Interval se ejecuta lo que esté en el evento OnTimer del TTimer, el cronómetro interno entonces vuelve a cero y se repite el proceso hasta que la aplicación termina o bién la propiedad Enabled se pone en falso, una aplicación obvia de este componente es la de un reloj.

Vamos a hacer una aplicación cronómetro para probar este componente y de paso ver cómo se trabaja por código las propiedades de los componentes.

Un cronómetro sencillo.

Comienza una aplicación nueva. En el formulario suelta dos Buttons y un Label de la paleta Standard, y de la paleta System un Timer. Pon la propiedad Enabled del Timer en false para prevenir que se dispare cuando la aplicación arranque. Limpia la propiedad Caption del Label. A uno de los Button cambia su Caption a "Comenzar" y al otro cambia su Caption a "Reset", el pimero será para arrancar o detener el cronómetro y el segundo para volver a cero la cuenta. Luego de estas modificaciones tienes que tener un formulario que se vea más o menos así:

Vista parcial del formulario en tiempo de diseño

Fig. 4 - Vista parcial del formulario en tiempo de diseño.

Ahora cámbiate al Editor de Código y llega hasta la declaración del formulario, debe verse así:

type
   TForm1 = class(TForm)
     Timer1: TTimer;
     Label1: TLabel;
     Button1: TButton;
     Button2: TButton;
   private
     { Private declarations }
   public
     { Public declarations }
   end;

Agregaremos una variable de clase a la clase TForm1 en la sección public la cual llamaremos Segundos y será de tipo integer, así:

type
   TForm1 = class(TForm)
     Timer1: TTimer;
     Label1: TLabel;
     Button1: TButton;
     Button2: TButton;
   private
     { Private declarations }
   public
     { Public declarations }
     Segundos: integer;
   end;

La cual tendremos que inicializar en cero. El mejor momento de hacerlo es cuando el formulario se carga, esto es en el evento OnCreate, así que usa el Inspector de Objetos, selecciona el Form1 y haz doble click en el evento OnCreate. Luego modifica el código de ese evento de forma tal que se vea así:

procedure TForm1.FormCreate(Sender: TObject);
begin
  Segundos:=0;
end;

Es decir asignarle cero a la variable Segundos, esto ocurrirá una sola vez cuando de comienzo a nuestra aplicación.
Nota: de nada sirve que escribas el procedimiento OnCreate manualmente sin usar el Inspector de Objeto ya que no se realiza la asociación entre ese procedimiento y el evento OnCreate del Form1.

Ahora selecciona el objeto Timer1 y modifica el evento OnTimer desde el Inspector de Objeto de forma que se vea así:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Segundos:=Segundos+1;
  Label1.Caption:=IntToStr(Segundos);
end;

Como había mencionado, este evento se ejecuta cada vez que el cronómetro interno del TTimer es igual o mayor a la propiedad Interval del mismo que por omisión vale 1000 milisegundos, es decir, 1 segundo, no lo modificaremos pues es justo lo que queremos. Lo que se hace aquí es sumar 1 a la variable de clase Segundos y luego mostrarla en el Label1 pero para ello tenemos que hacer una conversión de tipos ya que la propiedad Caption del Label es de tipo TCaption y Segundos es de tipo Integer, para lograr esto usamos una función predefinida llamada IntToStr que convierte cualquier tipo entero, tal como Integer, a un String, es decir a texto, TCaption es compatible con String.

Ahora modifica la propiedad OnClick del Button1 (el que tiene el Caption "Comenzar") de modo que se vea así:

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Timer1.Enabled = true then  // si el timer está corriendo...
    begin
      Timer1.Enabled:= false;      // detenerlo
      Button1.Caption:='Comenzar'; // y cambiar el caption del button
    end  // (aquí no se escribe punto y coma)
  else                             // sino ...
    begin
      Timer1.Enabled:= true;       // disparar el timer
      Button1.Caption:='Detener';  // y cambiar el caption del button.
    end;
end;

La lógica aquí es, preguntamos si el timer está corriendo, es decir su propiedad Enabled está en true, si lo está lo paramos poniendo en false esa propiedad y modificamos el Caption del Button para reflejar ese estado, si no está corriendo lo ponemos a correr y cambiamos el estado del Caption también. Nota que en el End antes del Else no se escribe punto y coma pues allí no termina la sentencia If.

Solo nos falta que el usuario tenga la posibilidad de poner en cero la variable Segundo. Para eso hemos puesto el otro Button, cuyo código en su evento OnClick debe ser este:

procedure TForm1.Button2Click(Sender: TObject);
begin
  Segundos:=0;
  Label1.Caption:=IntToStr(Segundos);
end;

No necesita mucha explicación, ¿cierto?. Compilamos y ejecutamos, si todo marcha bién deberías tener un cronómetro que marca los segundos. No creo que necesites instrucciones de cómo funciona el programa ¿eh? :).

En resumen.

Hemos dado un vistazo a los componente más comunmente usados en una aplicación Windows, hemos visto también alguna de sus propiedades así como ejemplo de su uso y una aplicación práctica de alguno de ellos. Espero que esto despierte tu imaginación y explores por tí mismo todas las posibilidades que te ofrece la VCL. En el próximo capítulo veremos algo más en profundidad lo que es el lenguaje Object Pascal.

Diego Romero -