Ir al contenido



Foto

Copiar formularios (reutilizar)

forms

  • Por favor identifícate para responder
16 respuestas en este tema

#1 Gaston

Gaston

    Advanced Member

  • Miembros
  • PipPipPip
  • 70 mensajes

Escrito 21 noviembre 2016 - 04:03

Hola gente, me da un poco de vergüenza postear de nuevo, pero cuando no encuentro respuestas en Saint Gugl vengo para esta zona.

 

El tema es, en teoría, simple, quiero reutilizar un formulario ya que hice un Form para un reporte y para el resto de los reportes (aporx. 7 u 8) son 90% lo mismo. Imagino que el método correcto no es copiar los archivos y cambiarles el nombre y luego agregarlos a mano, pero por ahí se hace así, no lo sé.

 

Si me pueden orientar un poco, se agradece.

 

Saludos.


  • 0

#2 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 771 mensajes
  • LocationArgentina

Escrito 21 noviembre 2016 - 05:18

Es algo muy sencillo de hacer, debes usar herencia visual.

 

El ejemplo mas sencillo es el siguiente, creas un nuevo formulario, y para ilustrar este ejemplo le pongo un TLabel por donde mas te guste y el siguiente codigo en su evento FormCreate


delphi
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3. Label1.Caption := 'este es ' + ClassName;
  4. end;

Luego se crea otro formulario, se agrega en la seccion uses de la interface el nombre de la unidad en donde esta el formulario que queremos heredar, en este caso es Uni1

 

Asi queda la Unit2:


delphi
  1. unit Unit2;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8. Unit1, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs;
  9.  
  10. type
  11. TForm2 = class(TForm1)
  12. private
  13. { private declarations }
  14. public
  15. { public declarations }
  16. end;

Al hacer esto, si pasas a la vista de formulario (F12) deberias ver en pantalla que el nuevo formulario tiene el Label. Si le pones a este formulario la propiedad Visible a True y ejecutas la aplicacion, vas a ver un Form1 con el Label a 'Este es TForm1' y un Form2 con el Label a 'Este es TForm2'


  • 1

#3 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.944 mensajes
  • LocationArgentina

Escrito 21 noviembre 2016 - 05:28

Ummm. Creo que el compañero Gaston se refiere a que tiene un form con componentes de reportes y quisiera reutilizarlo.

Yo la verdad es que no he utilizado hasta el momento ningún "report" de y/o para Lazarus.

 

Desconozco si hay alguno por defecto instalado, e incluso si es que CodeTyphon incluye algunos otros más.

En este punto soy un desconocido en la materia.

 

Al menos en Delphi se que hay suites de reportes que permiten guardar y abrir reportes en tiempo de ejecución, pero de ahí a que en runtime éste muestre los componentes adaptados a su propio caso no lo se.

 

Saludos,


  • 1

#4 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 771 mensajes
  • LocationArgentina

Escrito 21 noviembre 2016 - 05:37

Yo he usado herencia visual para ahorrar código y diseño en reportes, en donde iba colocando los componentes y propiedades comunes en las clases más abstractas. El primer ancestro de la jerarquía tenía el componente reporte sobre el form, y establecía algunas cosas básicas como el título y pie de página, tamaño de la hoja, configuración de la impresora.. también tiene su constructor sobrecargado en donde indicaba cual era el DataSet que se conectaba al reporte. Así de a poco se puede llegar a clonar reportes en un periquete y cambiar o agregar algo sin re hacer el resto.

POO aplicada a reportes
  • 1

#5 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.212 mensajes
  • LocationRepública Dominicana

Escrito 21 noviembre 2016 - 05:50

Pues tienes dos opciones utilizando el mismo formulario (Tres si contamos con la opción de agustín), ambas son sencillas y chapuceras:

 

1 - En el mismo Formulario agregas un TRadioGroup y sus items serían los nombres de los reportes, y filtras con un case..of ó if..else:


delphi
  1. case RadioGroup1.itemIndex of
  2. 0: //Mandamos a imprimir el reporte1
  3. 1: //Mandamos a imprimir el reporte2
  4. {...y Así sucesivamente}
  5. end;

2 - Agregas una variable pública en el formulario del reporte (Esa que se declara en la sección Public) y de acuerdo con ese valor haces lo mismo con lo anterior:


delphi
  1. //Llamas al formulario del reporte asignandole valor a la variable:
  2. Form2.TipoReporte := 1; //La variable se llamaría así TipoReporte
  3. Form2.ShowModal

y luego


delphi
  1. case TipoReporte of
  2. 0: //Mandamos a imprimir el reporte1
  3. 1: //Mandamos a imprimir el reporte2
  4. end;

Saludos.


  • 1

#6 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.944 mensajes
  • LocationArgentina

Escrito 21 noviembre 2016 - 07:35

Yo inicialmente cuando vi el título del hilo en lo primero que pensé es en herencia visual y usar frames.

 

La propuesta de Agustín me gusta. Lo que me pregunto es que tanto permitirá la suite de componentes trabajar y llevarse bien con la herencia visual.

Lo importante es que se analice bien que partes y hasta que punto existen elementos comunes y que es lo que hace distinto o particular a cada informe/reporte.

En base a eso se puede ver posibles alternativas.

 

Saludos,


  • 2

#7 Gaston

Gaston

    Advanced Member

  • Miembros
  • PipPipPip
  • 70 mensajes

Escrito 21 noviembre 2016 - 08:22

Delphius, diste en tecla  ;)

 

Lo que necesito es copiar un formulario que ya tiene componentes, los reportes en este caso no interfieren porque los tengo en un data module. Con unas imágenes por ahí se entiende mejor.

 

8c5b6229f4a66e8a4a1f95a6aced518co.jpg

 

Este formulario de arriba, llamémosle Form2, llama al siguiente formulario que llamaremos Form3:

 

3d814e6772fcc5c4bf8bf88004700079o.jpg

 
Lo que me gustaría hacer es varias copias del Form3 (Form4, Form5, etc.) para ser llamado desde Form2. Luego modificaría un poco el código de los formularios clonados para que llamen a los distintos reportes. Pero no sé si se puede hacer.
 
Agustín, Enecumene, ahora que lo expuse un poco mejor, quisiera saber si los métodos que me recomiendan me sirven para este caso.
Gracias por sus respuestas.
Saludos.

  • 0

#8 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.944 mensajes
  • LocationArgentina

Escrito 21 noviembre 2016 - 09:21

Si lo que se ve en la imagen es la estructura/diseño común a todos y que luego cada form incorpora más elementos propios y diseñados para su propósito la herencia visual es la mejor propuesta.

 

Crea el form2 que será la base (una especie de "plantilla") con los controles, eventos, y la programación necesaria.

Luego vas a hacer herencia visual de éste, tantos como necesites. ¿Como se hace? Archivo -> Nuevo. Luego en la lista de items de la izquierda busca la "categoría" elementos heredados.

Selecciona el subitem componente de proyecto heredado.

Ahora en la parte derecha, se te muestra los forms disponibles para hacer la herencia. Selecciona el form2. Acepta.

 

Ya tienes tu form heredado.

 

Ahora bien. Lazarus tiene sus bugs en este punto. La forma de aplicarlo es un poco más complicado. El bug se debe a un problema de orden de lectura del archivo .lfm del que será el form base. En ese enlace tienes los pasos correctos.

 

Aunque en este hilo se explican mejor los pasos. Ojalá esta poderosa característica (que suele pasar desapercibida por muchos programadores) pudiera implementarse correctamente en tiempo de diseño en el IDE. En términos lógicos funciona como yo he descripto, pero si lo haces observarás que no se muestran los controles bases que ha heredado de su padre.

 

Saludos, 


  • 2

#9 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.944 mensajes
  • LocationArgentina

Escrito 21 noviembre 2016 - 09:56

O de última puedes forzar el "refrezcado" del IDE para que muestre la herencia visual, si mantienes el orden de los archivos abiertos: primero abre el pas y el lfm del ancestro, luego los archivos del descendiente.

Luego ve al pas del ancestro y ve al menu Ver -> Cambiar la Vista Formulario/Unidad o con F11 para forzar al ide a que muestre el form. Repite ahora con el descendiente.

 

Lo acabo de probar así con un proyecto de prueba y funciona.

 

Saludos,


  • 2

#10 Gaston

Gaston

    Advanced Member

  • Miembros
  • PipPipPip
  • 70 mensajes

Escrito 21 noviembre 2016 - 10:45

Si lo que se ve en la imagen es la estructura/diseño común a todos y que luego cada form incorpora más elementos propios y diseñados para su propósito la herencia visual es la mejor propuesta.

 

Crea el form2 que será la base (una especie de "plantilla") con los controles, eventos, y la programación necesaria.

Luego vas a hacer herencia visual de éste, tantos como necesites. ¿Como se hace? Archivo -> Nuevo. Luego en la lista de items de la izquierda busca la "categoría" elementos heredados.

Selecciona el subitem componente de proyecto heredado.

Ahora en la parte derecha, se te muestra los forms disponibles para hacer la herencia. Selecciona el form2. Acepta.

 

Ya tienes tu form heredado.

 

 

Funciona perfecto, gracias! 

 

Lo único, pero que pasa siempre que agrego un formulario y lo explico por si alguien más novato que yo lo lee, es que si a la nueva unidad le cambiamos el nombre por default de unit1 por otro nombre y guardamos, todo bien, pero al compilar arroja un error porque en el lpi (la unidad principal) figura unit1 y no el nombre con el cual la guardamos, esto se soluciona de manera simple, en el .lpi cambiamos unit1 por el nombre que le dimos a la unidad y listo.

 

Saludos.


  • 0

#11 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.212 mensajes
  • LocationRepública Dominicana

Escrito 22 noviembre 2016 - 07:09

Una preguntonta, a mí entender utilizando la herencia en este caso, ¿no engrosa aún más la aplicación?, por esa razón en muchos casos no lo utilizo, por eso trabajo de la manera chapucera expuesto anteriormente (Aunque reconozco que lo expuesto por ustede es lo correcto).

 

Saludos.


  • 0

#12 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 771 mensajes
  • LocationArgentina

Escrito 22 noviembre 2016 - 08:34

Si, pero creo que es despreciable, porque los .dfm o .lfm heredados no incluyen los componentes del anterior.. a menos que les cambies propiedades. Obviamente que si en lo heredado agregas nuevos componentes, estos tienen que figurar.

 

De todos modos, es clasico de la POO que tenga estas desventajas: que sea mas lento, que es mas dificil, que al principio es mas complicado, que necesitas mas codigo, que crece el tamaño del ejecutable.. pero bueno tiene sus beneficios por otra parte, con algo hay que pagarlos!

 

Cuando hice la prueba en Lazarus de heredar usando el menu contextual, directamente me dio error. Igual hacerlo a "mano" tampoco es tanto lio. Una cosa que me llama la atencion de Lazarus es que no podes ver el form como su representacion en texto, esto en Delphi si podes hacerlo usando boton derecho sobre el form -> View as Text. Extrañamente tambien, no hace falta cambiar la declaracion en el .LFM en la primer linea, que por defecto es object Form2: TForm2 a inherited. Al cambiar la clase ancestro, si se abre el .LFM con un editor de textos, se ve que el solo ya hizo el cambio a inherited

 

Si bien te habia entendido mal cual era el proposito, la tecnica es la misma, creas un formulario "abstracto" y luego en los descendientes agregas las caracteristicas que faltan.

 

Que no te de verguenza, que durante mucho tiempo yo hacia exactamente lo mismo, Tambien llegue a hacer lo mismo que comenta enecumene. Pero la alternativa mas "poderosa" es esta, osea como dije mas arriba, es Orientacion a Objetos aplicada a Formularios. Es mas dificil si, pero con el tiempo es la alternativa mas segura y que te hara trabajar menos

 

Por ultimo, quiero decir que si bien esta todo hermoso, hay que tener cuidado y no abusar de la herencia (tanto de clases como visual) porque suele tener varios problemas, por ejemplo, cuando tenes dos descendientes que agregan la funcionalidadA y la funcionalidadB y luego necesitas un descendienteC que tambien tiene que tener la funcionalidadA y la funcionalidadB (es imposible juntarlos y tenes que copiar todo). Y tambien para el caso de la herencia visual, ha pasado y es muy molesto, que los IDE no la suelen trabajar al 100% y hay errores que te hacen perder mas tiempo del que se gana.

 

Hay algunos controles que son bastante complicados de manejar con herencia visual. Con el tiempo uno le encuentra las mañas, por ejemplo, los controles como TGridPanel que manejan colecciones de elementos, a veces no heredan dichas colecciones y se te corrompe el form heredado; entonces es cuando uso hace ese trabajo por codigo mas que en diseño


Editado por Agustin Ortu, 22 noviembre 2016 - 08:39 .

  • 2

#13 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.944 mensajes
  • LocationArgentina

Escrito 22 noviembre 2016 - 08:36

Una preguntonta, a mí entender utilizando la herencia en este caso, ¿no engrosa aún más la aplicación?, por esa razón en muchos casos no lo utilizo, por eso trabajo de la manera chapucera expuesto anteriormente (Aunque reconozco que lo expuesto por ustede es lo correcto).

 

Saludos.

 

Obviamente, se está añadiendo más forms a la aplicación.

En ocasiones es útil la herencia visual, y en otras es viable aprovechar un mismo form para muchas cosas.

Todo depende de que controles, y que cantidad de éstos se requieren. Y además hay que considerar que tan similares o en su defecto, que tan diferentes, son entre ellos.

 

Lo de aprovechar un form, o hasta incluso un mismo reporte (obviamente teniendo cuidado de apuntar al dataset apropiado para el caso) es posible. Habría que saber en detalle que los compone, o bien, diseñarlos de forma tal que todos puedan ser "presentados" en él.

 

La otra alternativa que puede ser muy útil y reducir el uso de forms "clonados" es si resulta ser que todos estos forms tienen el mismo aspecto de diseño. Es decir si visualmente los form4, 5, etc tienen los mismos controles y en el mismo lugar lo que se puede hacer es indicarle al form que operatoria (y/o tipo de informe) va a representar al momento de ser invocado.

 

Una implementación hipotética:


delphi
  1. procedure TForm3.EstablecerInforme(Informe: TTipoInforme);
  2. begin
  3. case Informe of
  4. iPago: // que hacer si el informe es de pago
  5. iConsultaMovimiento // que hacer si el informe es de movimientos
  6. // etc.
  7. end;

Este procedimiento se encargaría de establecer/cambiar/configurar/adaptar las propiedades de los controles de ser necesario, cambiar el texto (como por ejemplo que diga en el título Pagos, Consultas, etc), llenar el combo con las opciones a cada caso, etc. Incluso se puede diseñar el procedimiento para recibir como parámetro el dataset en cuestión, ajustar el componente report a su gusto, etc.

 

Lo que lo va a hacer actuar distinto es justamente cada llamada. Por ejemplo cuando se presione el botón Libro Bancos, se le pasará como parámetro un valor, y cuando se presione el botón 5, el valor sera otro adecuado para el caso:


delphi
  1. procedure TForm2.BotonLibroBancosClick(Sender: TObject);
  2. begin
  3. Form3.EstablecerInforme(eLibroBancos);
  4. // Form3.EstablecerInforme('Libros de Bancos', datasetlibroBancos); // otra forma de hacerlo
  5. Form3.Show;
  6. end;

En fin, la creatividad es el límite.

 

Saludos,


  • 1

#14 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.944 mensajes
  • LocationArgentina

Escrito 22 noviembre 2016 - 08:43

Anoche me olvidé de dar una pequeña advertencia si se usa herencia visual con forms en Lazarus.

En el enlace oficial de la wiki que puse, hay una sección ToDo que vale la pena considerar: hay que tener cuidado con los eventos heredados porque aparentemente funciona parcialmente.

 

Yo tomo nota de esto, porque hago uso de frames y herencia de frames en mi proyecto, y si bien hasta ahora no vi problemas de eventos heredados. Mejor vale la pena tenerlo en cuenta... aunque ahora que recuerdo, creo que eso podría explicar porque algunas cosillas no me funcionaron cuando estuve probando sobreescribir un procedimiento...

 

Saludos,


  • 1

#15 Gaston

Gaston

    Advanced Member

  • Miembros
  • PipPipPip
  • 70 mensajes

Escrito 23 noviembre 2016 - 03:05

Una preguntonta, a mí entender utilizando la herencia en este caso, ¿no engrosa aún más la aplicación?, por esa razón en muchos casos no lo utilizo, por eso trabajo de la manera chapucera expuesto anteriormente (Aunque reconozco que lo expuesto por ustede es lo correcto).

 

Saludos.

 

Yo pensaba que el efecto era el contrario  :sad:

A veces se aprende más en los foros, es donde está la experiencia.

 

Si, pero creo que es despreciable, porque los .dfm o .lfm heredados no incluyen los componentes del anterior.. a menos que les cambies propiedades. Obviamente que si en lo heredado agregas nuevos componentes, estos tienen que figurar.

 

De todos modos, es clasico de la POO que tenga estas desventajas: que sea mas lento, que es mas dificil, que al principio es mas complicado, que necesitas mas codigo, que crece el tamaño del ejecutable.. pero bueno tiene sus beneficios por otra parte, con algo hay que pagarlos!

 

Cuando hice la prueba en Lazarus de heredar usando el menu contextual, directamente me dio error. Igual hacerlo a "mano" tampoco es tanto lio. Una cosa que me llama la atencion de Lazarus es que no podes ver el form como su representacion en texto, esto en Delphi si podes hacerlo usando boton derecho sobre el form -> View as Text. Extrañamente tambien, no hace falta cambiar la declaracion en el .LFM en la primer linea, que por defecto es object Form2: TForm2 a inherited. Al cambiar la clase ancestro, si se abre el .LFM con un editor de textos, se ve que el solo ya hizo el cambio a inherited

 

Si bien te habia entendido mal cual era el proposito, la tecnica es la misma, creas un formulario "abstracto" y luego en los descendientes agregas las caracteristicas que faltan.

 

Que no te de verguenza, que durante mucho tiempo yo hacia exactamente lo mismo, Tambien llegue a hacer lo mismo que comenta enecumene. Pero la alternativa mas "poderosa" es esta, osea como dije mas arriba, es Orientacion a Objetos aplicada a Formularios. Es mas dificil si, pero con el tiempo es la alternativa mas segura y que te hara trabajar menos

 

Por ultimo, quiero decir que si bien esta todo hermoso, hay que tener cuidado y no abusar de la herencia (tanto de clases como visual) porque suele tener varios problemas, por ejemplo, cuando tenes dos descendientes que agregan la funcionalidadA y la funcionalidadB y luego necesitas un descendienteC que tambien tiene que tener la funcionalidadA y la funcionalidadB (es imposible juntarlos y tenes que copiar todo). Y tambien para el caso de la herencia visual, ha pasado y es muy molesto, que los IDE no la suelen trabajar al 100% y hay errores que te hacen perder mas tiempo del que se gana.

 

Hay algunos controles que son bastante complicados de manejar con herencia visual. Con el tiempo uno le encuentra las mañas, por ejemplo, los controles como TGridPanel que manejan colecciones de elementos, a veces no heredan dichas colecciones y se te corrompe el form heredado; entonces es cuando uso hace ese trabajo por codigo mas que en diseño

 

Es decir, no hay que abusar y usarlo para cosas simples. El primer "problemita" que encontré fue con el botón imprimir, tuve que hacerlo invisible y crear uno nuevo. Ahora evalúo la posibilidad de declarar el procedimiento imprimir en el Form1 como virtual y en el Form2 como override a ver si funciona, según anduve leyendo suele traer complicaciones, veremos...

 

Obviamente, se está añadiendo más forms a la aplicación.

En ocasiones es útil la herencia visual, y en otras es viable aprovechar un mismo form para muchas cosas.

Todo depende de que controles, y que cantidad de éstos se requieren. Y además hay que considerar que tan similares o en su defecto, que tan diferentes, son entre ellos.

 

Lo de aprovechar un form, o hasta incluso un mismo reporte (obviamente teniendo cuidado de apuntar al dataset apropiado para el caso) es posible. Habría que saber en detalle que los compone, o bien, diseñarlos de forma tal que todos puedan ser "presentados" en él.

 

La otra alternativa que puede ser muy útil y reducir el uso de forms "clonados" es si resulta ser que todos estos forms tienen el mismo aspecto de diseño. Es decir si visualmente los form4, 5, etc tienen los mismos controles y en el mismo lugar lo que se puede hacer es indicarle al form que operatoria (y/o tipo de informe) va a representar al momento de ser invocado.

 

Una implementación hipotética:


delphi
  1. procedure TForm3.EstablecerInforme(Informe: TTipoInforme);
  2. begin
  3. case Informe of
  4. iPago: // que hacer si el informe es de pago
  5. iConsultaMovimiento // que hacer si el informe es de movimientos
  6. // etc.
  7. end;

Este procedimiento se encargaría de establecer/cambiar/configurar/adaptar las propiedades de los controles de ser necesario, cambiar el texto (como por ejemplo que diga en el título Pagos, Consultas, etc), llenar el combo con las opciones a cada caso, etc. Incluso se puede diseñar el procedimiento para recibir como parámetro el dataset en cuestión, ajustar el componente report a su gusto, etc.

 

Lo que lo va a hacer actuar distinto es justamente cada llamada. Por ejemplo cuando se presione el botón Libro Bancos, se le pasará como parámetro un valor, y cuando se presione el botón 5, el valor sera otro adecuado para el caso:


delphi
  1. procedure TForm2.BotonLibroBancosClick(Sender: TObject);
  2. begin
  3. Form3.EstablecerInforme(eLibroBancos);
  4. // Form3.EstablecerInforme('Libros de Bancos', datasetlibroBancos); // otra forma de hacerlo
  5. Form3.Show;
  6. end;

En fin, la creatividad es el límite.

 

Saludos,

 

Tomo nota, parece correcto adaptar el procedure Imprimir que invoque según una variable a cada reporte. Muy buenas sus exposiciones.

 

Saludos.


  • 0

#16 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 771 mensajes
  • LocationArgentina

Escrito 23 noviembre 2016 - 04:22

Si la herencia de eventos funciona mal en lazarus, es facil de solucionar


delphi
  1. type
  2. TReporteBase = class(TForm)
  3. procedure ButtonViewReportClick(Sender: TObject);
  4. procedure ButtonPrintReportClick(Sender: TObject);
  5. protected
  6. procedure DoViewReport; virtual; abstract; // implementar en descendientes
  7. procedure DoPrintReport; virtual; abstract; // implementar en descendientes
  8. end;
  9.  
  10. procedure TReporteBase.ButtonViewReportClick(Sender: TObject);
  11. begin
  12. DoViewReport;
  13. end;
  14.  
  15. procedure TReporteBase.ButtonPrintReportClick(Sender: TObject);
  16. begin
  17. DoPrintReport;
  18. end;

Otra cosa, que no se si aplicara a FreePascal, Lazarus y cia: 

 

1 - Genericos en el form. Al IDE no le gusta. Simplemente no vas a poder abrir el Form en tiempo de edicion. Ejemplo:


php
  1.   TDetalleForm<T> = class(TForm) // esa "T" no le gusta al IDE; al menos en Delphi
  2.   end;

2 - Declarar al form como abstracto. Mismo problema que el caso anterior, al IDE no le gusta para nada. A simple vista, te estas privando de uno de los conceptos fundamentales de POO: las clases abstractas. Pero es un error que no podes escapar y no queda otra. Lamentablemente, todos los TForm que quieras diseñar con el IDE deberan ser clases concretas


delphi
  1. TReporteBase = class abstract(TForm) // ka-boom! crash al abrir este form en el IDE
  2. end;

Tanto 1 y 2 no dan problema alguno si escribes todo el codigo a "pulmon" sin usar el diseñador grafico, es decir, solo un archivo ,pas 


Editado por Agustin Ortu, 23 noviembre 2016 - 04:24 .

  • 1

#17 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.944 mensajes
  • LocationArgentina

Escrito 23 noviembre 2016 - 04:40

Si la herencia de eventos funciona mal en lazarus, es facil de solucionar


delphi
  1. type
  2. TReporteBase = class(TForm)
  3. procedure ButtonViewReportClick(Sender: TObject);
  4. procedure ButtonPrintReportClick(Sender: TObject);
  5. protected
  6. procedure DoViewReport; virtual; abstract; // implementar en descendientes
  7. procedure DoPrintReport; virtual; abstract; // implementar en descendientes
  8. end;
  9.  
  10. procedure TReporteBase.ButtonViewReportClick(Sender: TObject);
  11. begin
  12. DoViewReport;
  13. end;
  14.  
  15. procedure TReporteBase.ButtonPrintReportClick(Sender: TObject);
  16. begin
  17. DoPrintReport;
  18. end;

Otra cosa, que no se si aplicara a FreePascal, Lazarus y cia: 

 

1 - Genericos en el form. Al IDE no le gusta. Simplemente no vas a poder abrir el Form en tiempo de edicion. Ejemplo:


php
  1.   TDetalleForm<T> = class(TForm) // esa "T" no le gusta al IDE; al menos en Delphi
  2.   end;

2 - Declarar al form como abstracto. Mismo problema que el caso anterior, al IDE no le gusta para nada. A simple vista, te estas privando de uno de los conceptos fundamentales de POO: las clases abstractas. Pero es un error que no podes escapar y no queda otra. Lamentablemente, todos los TForm que quieras diseñar con el IDE deberan ser clases concretas


delphi
  1. TReporteBase = class abstract(TForm) // ka-boom! crash al abrir este form en el IDE
  2. end;

Tanto 1 y 2 no dan problema alguno si escribes todo el codigo a "pulmon" sin usar el diseñador grafico, es decir, solo un archivo ,pas 

 

No lo he probado, pero creo que Lazarus también protestaría con estas propuestas.

En cierta forma en el concepto de Form es donde se rompe el concepto POO en Object Pascal.

 

Cuando definimos un:


delphi
  1. TMiForm = class(TForm);
  2. // ...
  3. end;

Estamos haciendo una clase.

 

Y más adelante nuestro:


delphi
  1. var
  2. MiForm: TMiForm;

Es una instancia.

 

El problema está del lado visual a nivel IDE. Para el IDE los forms en el que disponemos los controles le es una cosa rara. ¡Ese form es tanto una clase como un objeto! Si lo vemos como objeto no puede ser abstracto, a nivel de clase, es concedible una definición y hasta un diseño de uso abstracto (si así no fuera, no sería posible la herencia visual)

 

En lugar de intentar forzar ese nivel de abstracción lo que si podemos hacer es darle los métodos que así sean. Conceptualmente su uso sigue siendo abstracto y podremos hacer la herencia y sobreescritura que uno requiera.

 

Es cierto que Lazarus parece tener sus problemas con la herencia visual. Tendría que hacer una prueba muy completa y detallada para encontrar que tipos de eventos son los que parcialmente funcionan y cuales no. Recuerdo que durante unas pruebas con frames tuve dificultades pero también he podido seguir adelante. Lo comenté en mi hilo.

 

Hasta ahora me está resultando...

 

Saludos,

 

 

Saludos,


  • 1





Etiquetado también con una o más de estas palabras: forms