#!/bin/bash export LIBOVERLAY_SCROLLBAR=0 export UBUNTU_MENUPROXY=0 ./yourapplication
Por más información pueden leer aquí. Invocamos a Lazarus/Typhon. Cuando abre presionamos File|New… Aparece un formulario y seleccionamos Application.
Con esto se crea un esqueleto de una aplicación y un formulario, para una aplicación visual. En Lazarus el formulario aparece en una ventana independiente, mientras que en Typhon aparece en la pestaña de Designer. Si el formulario no aparece puede que haya quedado fuera del espacio de las pantallas. Al menos me ocurre cuando trabajo en un entorno con muchas pantallas.
Para traer al formulario dentro de la ventana de Designer presionamos el botón de centrar. Allí nos aparece nuestro formulario.
Arriba generalmente (puede estar abajo si así lo configuraron) se encuentra la barra de componentes y el menú principal del ambiente. Allí se encuentran las principales operaciones para desarrollo, compilación y edición del código. También hay un conjunto importante de componentes visuales que se agregarán al código simplemente clickeando en el componente y luego en el formulario donde se agrega.
Lo básico de nuestro proyecto está construído. Ahora debemos salvarlo y darle un nombre. Vamos a File| Save As…
Navegamos hasta el directorio de nuestros proyectos y creamos un nuevo directorio para este. Presionando [Create Forlder] le damos el nombre ‘wordpressreader’.
Ya tenemos un proyecto guardado. Ahora debemos ponerle un menú a nuestro formulario. En la pestaña [Standard] de componentes hacemos click en el primer ítem (TmainMenu).
Para editar en Menú, le damos botón derecho y seleccionamos ‘MenuEditor’.
Agregamos dos ‘MenuItem’. Para ello presionamos dos veces el botón [Add Menu Item]. Luego con botón derecho sobre MenuItem1, seleccionamos [Edit Caption].
Esto nos permite renombrar en ítem 1 del menú. Le ponemos ‘Configure’. Al siguiente le ponemos ‘Exit’.
No hay que olvidar de tanto en tanto presionar [Save] {Ctrl+S} o {Shift+Ctrl+S}. Agregamos un manejador de eventos. Botón derecho y [Add OnClick Handler]
Para el Menu Item Exit agregamos en el código:
Application.Terminate;
Nótese que si esperamos un poco la ayuda contextual busca en los atributos y métodos del objeto y nos brinda un dropdown con los posibles valores. Al seleccionar Terminate y dar [Enter] se completa el código incluyendo el punto y coma.
También generamos un Event Handler para Item Configure. Por ahora no ponemos nada allí. Volvemos al Designer del Form1, y elegimos la pestaña SQLdb de la Barra de componentes, y agregamos los siguientes componentes al Form1: TMySQL40Connection, TMySQL41Connection, TMySQL50Connection, TMySQL51Connection, TMySQL55Connection, TMySQL56Connection y TMySQL57Connection.
Agregamos de la pestaña también un TSQLTransaction y un TSQLQuery. En la pestaña ‘Data Access’ agregamos un TDataSource. Agregamos de la pestaña Additional un TPairSplitter.
Seleccionamos el PairSplitter (que de lo contrario es invisible) y le cambiamos el atributo de orientación. En el atributo Splitter Type ponemos pstVertical.
El Pair Splitter consiste en un contenedor que incluye otros dos contenedores de componentes gráficos con un TSplitter en medio, que nos permitirá agrandar a un componente mientras se achica el otro. Haciendo click en la parte de arriba y en la de abajo podemos identificar ambos contenedores.
Agregamos en el contenedor superior un TDBGrid y en el inferior un TDBMemo de la pestaña de ‘Data Controls’.
Agregamos un DBMemo (DBMemo2) en el contenedor inferior (lower container). Modificamos el atributo Align = alTop y Height=48. Esto permite alinear DBMemo2 a la parte superior del contenedor inferior (lower container). Modificamos todos los componentes para que llenen el espacio del contenedor, para cada uno de PairSplitter y para el DBGrid y el DBMemo. Les ponemos Align=alClient. También ponemos ScrollBars=ssAutoBoth.
Y nos queda el aspecto correcto.
Ahora debemos configurar los atributos de los objetos relacionados para que todo funcione correctamente. Suponemos que nos conectaremos a una base de datos MySQL de nombre ‘MySQLDatabase’, con el usuario ‘database-user’, y la password ‘MyV3rYC0mp73xP45w0rd’, en el servidor ‘localhost’ y por el puerto ‘3306’ (default). Para los objetos MySQLxyConnection vamos a tener que modificar los siguientes parámetros en tiempo de ejecución.
DatabaseName:='MySQLDatabase'; KeepConnection:=true; Password:='MyV3rYC0mp73xP45w0rd'; Transaction:=SQLTransaction1; UserName:='database-user'; Connected:=true;
Pero vamos a tener que probar una a una para verificar qué versión de cliente MySQL tenemos en el sistema. Para SQLTransaction1 tenemos que configurar los siguientes:
DataBase:=MySQLxyConnection1; //La que esté activa Active:=true
Para el SQLQuery1 debemos configurar lo siguiente:
DataBase:=MySQLxyConnection1; //La que esté activa SQL:='SELECT * FROM MySQLDatabase.wp_posts ORDER BY wp_posts.post_modified ASC;'; Transaction:=SQLTransaction1; Active:=true;
No se asigna el atributo DataSource en SQLQuery1 porque daría un error de dependencia circular. Para el componente DataSource1 se configura el atributo DataSet.
DataSet:=SQLQuery1;
Los siguientes elementos se configuran en tiempo de diseño, como se explica aquí. El DBGrid1 dentro del PairSplitter se le debe vincular el DataSource1. Al componente DBMemo1 se le agrega el DataSource y el DataField como se indica.
PairSplitter1
PairSplitterSide1
DBGrid1
DataSource:=DataSource1;
PairSplitterSide2
DBMemo1
DataSource:=DataSource1;
DataField:=’post_content’;
Agregamos un segundo formulario (Form2)
Y nos aparece el nuevo formulario.
Al nuevo formulario debemos agregarle los TLabeledEdit de la pestaña de ‘Additional’.
Debemos modificar el atributo LabelPosition a lpLeft, para que la etiqueta quede a la izquierda del cuadro de texto.
Se corrige el tamaño para que queden elegantes en el formulario. Tanto como se pueda. Debemos editar la Etiqueta para que quede algo significativo. EditLabel.Caption es el contenido de la etiqueta. Y Text es el contenido del Edit Box.
Agregamos un Botón con Caption Activate o Login o Connect. También editamos el texto de las cajas de edición para dejarlo de esta manera:
Además renombramos las EditBoxes con los nombres:
LabeledEditUser; LabeledEditPassword; LabeledEditDatabase; LabeledEditServer; LabeledEditPort;
En la Unit2 debemos agregar en la sección ‘Implementation’, que usa a la Unit1.
Para incluir la Unit2 en la Unit1, se declara en la sentencia uses.
Esta es la forma correcta para que no haya errores por dependencias circulares. En el Form2 seleccionamos el evento OnClick del Botón y agregamos el siguiente código.
procedure TForm2.Button1Click(Sender: TObject); begin Form1.user:= LabeledEditUser.Text; Form1.password:= LabeledEditPassword.Text; Form1.database:= LabeledEditDatabase.Text; Form1.server:= LabeledEditServer.Text; Form1.port:= LabeledEditPort.Text; self.Close; end;
Esto tomará los parámetros de la conexión al cliente MySQL y los pasará al Form1 en las variables correspondientes. En el Form1 debemos editar el evento del ítem de menú Configure. En la sección public debemos crear las variables de pasaje de parámetros.
public user, password, database,server,port: string; end;
Entre {$R *.frm} y { TForm1 } creamos un procedimiento auxiliar con el siguiente código
{$R *.frm} procedure MyConnected; var messagestring :string; begin messagestring:= ''; if Form1.MySQL40Connection1.Connected then messagestring:= messagestring + 'MySQL40 '; if Form1.MySQL41Connection1.Connected then messagestring:= messagestring + 'MySQL41 '; if Form1.MySQL50Connection1.Connected then messagestring:= messagestring + 'MySQL50 '; if Form1.MySQL51Connection1.Connected then messagestring:= messagestring + 'MySQL51 '; if Form1.MySQL55Connection1.Connected then messagestring:= messagestring + 'MySQL55 '; if Form1.MySQL56Connection1.Connected then messagestring:= messagestring + 'MySQL56 '; if Form1.MySQL57Connection1.Connected then messagestring:= messagestring + 'MySQL57 '; if (messagestring='') then messagestring:= 'Connected '+ messagestring else messagestring:='Not Conencted'; ShowMessage(messagestring); end; { TForm1 }
Esta función es solo de diagnóstico, en la versión final no se utiliza. Y luego agregamos el siguiente código en la función del evento del Menú Configure (MenuItem1):
{ TForm1 } procedure TForm1.MenuItem1Click(Sender: TObject); begin Form2.ShowModal; //Add Unit2 in uses... ShowMessage('This is a database' + database + ' password:'+ password + ' user:'+ user + ' server:'+ server + ' port:' + port ); //use parameters try MySQL40Connection1.DatabaseName:=database; MySQL40Connection1.KeepConnection:=true; MySQL40Connection1.Password:=password; MySQL40Connection1.UserName:=user; MySQL40Connection1.HostName:=server; MySQL40Connection1.Port:=StrToInt(port); MySQL40Connection1.KeepConnection:=true; //<---- MySQL40Connection1.Connected:=true; MySQL40Connection1.Open; finally if MySQL40Connection1.Connected then begin SQLTransaction1.DataBase:=MySQL40Connection1; SQLTransaction1.Active:=true; SQLQuery1.DataBase:=MySQL40Connection1; SQLQuery1.Transaction:=SQLTransaction1; SQLQuery1.SQL.Text:='SELECT * FROM '+ database + '.wp_posts ORDER BY wp_posts.post_modified ASC;'; SQLQuery1.Active:=true; end else begin try MySQL41Connection1.DatabaseName:=database; MySQL41Connection1.KeepConnection:=true; MySQL41Connection1.Password:=password; MySQL41Connection1.UserName:=user; MySQL41Connection1.HostName:=server; MySQL41Connection1.Port:=StrToInt(port); MySQL41Connection1.KeepConnection:=true; //<---- MySQL41Connection1.Connected:=true; MySQL41Connection1.Open; finally if MySQL41Connection1.Connected then begin SQLTransaction1.DataBase:=MySQL41Connection1; SQLTransaction1.Active:=true; SQLQuery1.DataBase:=MySQL41Connection1; SQLQuery1.Transaction:=SQLTransaction1; SQLQuery1.SQL.Text:='SELECT * FROM '+ database + '.wp_posts ORDER BY wp_posts.post_modified ASC;'; SQLQuery1.Active:=true; end else begin try MySQL50Connection1.DatabaseName:=database; MySQL50Connection1.KeepConnection:=true; MySQL50Connection1.Password:=password; MySQL50Connection1.UserName:=user; MySQL50Connection1.HostName:=server; MySQL50Connection1.Port:=StrToInt(port); MySQL50Connection1.KeepConnection:=true; //<---- MySQL50Connection1.Connected:=true; MySQL50Connection1.Open; finally if MySQL50Connection1.Connected then begin SQLTransaction1.DataBase:=MySQL50Connection1; SQLTransaction1.Active:=true; SQLQuery1.DataBase:=MySQL50Connection1; SQLQuery1.Transaction:=SQLTransaction1; SQLQuery1.SQL.Text:='SELECT * FROM '+ database + '.wp_posts ORDER BY wp_posts.post_modified ASC;'; SQLQuery1.Active:=true; end else begin try MySQL51Connection1.DatabaseName:=database; MySQL51Connection1.KeepConnection:=true; MySQL51Connection1.Password:=password; MySQL51Connection1.UserName:=user; MySQL51Connection1.HostName:=server; MySQL51Connection1.Port:=StrToInt(port); MySQL51Connection1.KeepConnection:=true; //<---- //MySQL51Connection1.Connected:=true; MySQL51Connection1.Open; finally if MySQL51Connection1.Connected then begin SQLTransaction1.DataBase:=MySQL51Connection1; SQLTransaction1.Active:=true; SQLQuery1.DataBase:=MySQL51Connection1; SQLQuery1.Transaction:=SQLTransaction1; SQLQuery1.SQL.Text:='SELECT * FROM '+ database + '.wp_posts ORDER BY wp_posts.post_modified ASC;'; SQLQuery1.Active:=true; end else begin try MySQL55Connection1.DatabaseName:=database; MySQL55Connection1.KeepConnection:=true; MySQL55Connection1.Password:=password; MySQL55Connection1.UserName:=user; MySQL55Connection1.HostName:=server; MySQL55Connection1.Port:=StrToInt(port); MySQL55Connection1.KeepConnection:=true; //<---- MySQL55Connection1.Connected:=true; MySQL55Connection1.Open; finally if MySQL55Connection1.Connected then begin SQLTransaction1.DataBase:=MySQL55Connection1; SQLTransaction1.Active:=true; SQLQuery1.DataBase:=MySQL55Connection1; SQLQuery1.Transaction:=SQLTransaction1; SQLQuery1.SQL.Text:='SELECT * FROM '+ database + '.wp_posts ORDER BY wp_posts.post_modified ASC;'; SQLQuery1.Active:=true; end else begin try MySQL56Connection1.DatabaseName:=database; MySQL56Connection1.KeepConnection:=true; MySQL56Connection1.Password:=password; MySQL56Connection1.UserName:=user; MySQL56Connection1.HostName:=server; MySQL56Connection1.Port:=StrToInt(port); MySQL56Connection1.KeepConnection:=true; //<---- MySQL56Connection1.Connected:=true; MySQL56Connection1.Open; finally if MySQL56Connection1.Connected then begin SQLTransaction1.DataBase:=MySQL56Connection1; SQLTransaction1.Active:=true; SQLQuery1.DataBase:=MySQL56Connection1; SQLQuery1.Transaction:=SQLTransaction1; SQLQuery1.SQL.Text:='SELECT * FROM '+ database + '.wp_posts ORDER BY wp_posts.post_modified ASC;'; SQLQuery1.Active:=true; end else begin try MySQL57Connection1.DatabaseName:=database; MySQL57Connection1.KeepConnection:=true; MySQL57Connection1.Password:=password; MySQL57Connection1.UserName:=user; MySQL57Connection1.HostName:=server; MySQL57Connection1.Port:=StrToInt(port); MySQL57Connection1.KeepConnection:=true; //<---- MySQL57Connection1.Connected:=true; MySQL57Connection1.Open; finally if MySQL57Connection1.Connected then begin SQLTransaction1.DataBase:=MySQL57Connection1; SQLTransaction1.Active:=true; SQLQuery1.DataBase:=MySQL57Connection1; SQLQuery1.Transaction:=SQLTransaction1; SQLQuery1.SQL.Text:='SELECT * FROM '+ database + '.wp_posts ORDER BY wp_posts.post_modified ASC;'; SQLQuery1.Active:=true; end else begin ShowMessage(' Did not find a suitable version of MySQL Client.'); end; end; //try end; //57 end; //finally end; //56 end; //finally end; //55 end; //finally end; //51 end; //finally end; //50 end;//finally end; //41 end;//finally MyConnected; //tell which database is connected {SQLTransaction1.DataBase:=MySQLConnection; SQLTransaction1.Active:=true; SQLQuery1.DataBase:=MySQLConnection; SQLQuery1.Transaction:=SQLTransaction1; SQLQuery1.SQL.Text:='SELECT * FROM '+ database + '.wp_posts ORDER BY wp_posts.post_modified ASC;'; SQLQuery1.Active:=true;} DataSource1.DataSet:=SQLQuery1; DBGrid1.DataSource:=DataSource1; DBMemo1.DataSource:=DataSource1; DBMemo1.DataField:='post_content'; end; //MenuItem1Click
Salvamos todo y podemos compilarlo y correrlo. Haciendo click en Configure nos aparece el form2 y podemos ingresar los parámetros de conexión a la base de datos. Haciendo Click en Activate, se conecta. Aparecerá un Message que nos modtrará los parámetros de conexión a la base de datos. Le damos OK. En Typhon el componente 51 dá un error no capturable en un mensaje si no encuentra su cliente de MySQL instalado.
TMySQL51Connection can not work with the installed MySQL client version: Expected (5.1), got (5.5.57). Press OK to ignore and risk data corruption. Press Abort to kill the program.
Es un problema de ese componente, ya que los otros componentes son capturados por el try finally. Dándole OK continúa. Y podemos recorrer los registros de la base y buscar el texto de nuestros posts perdidos. Recorremos los registros en el DBGrid superior, y nos aparece la información del post en el DBMemo abajo.
Este es el Proyecto Typhon. ¡Actualizado!
Este es el Proyecto Lazarus. ¡Actualizado! Probado en lazarus-1.8.0RC4-fpc-3.0.4rc1-win32.