Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Gráficos (https://www.clubdelphi.com/foros/forumdisplay.php?f=8)
-   -   Optimizar velocidad de creacion objetos tpanel (https://www.clubdelphi.com/foros/showthread.php?t=78761)

Toni 15-05-2012 18:56:21

Optimizar velocidad de creacion objetos tpanel
 
Hola a todos,

Tengo desarrollada una clase que me permite crear de forma dinamica una representacion grafica mediante objetos tpanel. A esta clase le paso como parametro un dataset y en funcion de unos datos crea dinamicamente esta representacion. Utilizo el tpanel porque tiene las caracteristicas de disponer ya los eventos onclick y algun otro que utilizo por cada objeto creado.

Esta representacion grafica utiliza unos 2000-3000 objectos tpanel de unas dimensiones muy pequeñas (9x9)
Y el principal problema lo tengo en la creacion de los objetos pues tarda mucho tiempo. Entorno a unos 20-30 o mas segundos. Lo cual no es nada aceptable cuando un usuario abre dicha pantalla.

Neftali [Germán.Estévez] 16-05-2012 10:14:49

Tal vez la idea está bien para pocos objetos, pero está visto que para un número grande la cosa se desmadra.
Creo que debes ir hacia componentes específicos de dibujo, tipo TSimpleGraph, del que ya he hablado otras veces aquí.

Te lo digo por experiencia, ya que lo he utilizado bastante y con muchos objetos. Aquí hace tiempo hablé de él y coloqué algunas imágenes (Imagen 1 y Imagen 2) donde puedes ver la cantidad de objetos que se definen (en el caso de explanadas, pueden llegar a 7000).

Este componente ya te permite realizar multitud de operaciones con lo elementos que añades; Ya poseen eventos, y operaciones de zoom, pan, impresión, exportación...

Toni 16-05-2012 10:18:12

Disculpar que me quede a medias ayer con la explicación.

Esta clase que comentaba una vez crea todos estos objetos y estan visibles, normalmente ocupan mas espacio que el tamaño del formulario y por eso activo las barras de desplazamiento del mismo. La cuestion es que una vez creado lo gestiona correctamente, es decir que si por ejemplo cambio de formulario y vuelvo al que tiene esta grafica lo repinta en un tiempo un tiempo aceptable (1s). Por lo que el problema solo esta en la creación dinamica de los objetos.

Un detalle mas es que no puedo tener creada la grafica de antemanos pues va en funcion de la que seleccione el usuario.

La pregunta es, como podria optimizar esto usuando quizas otro componente de la VCL o quizas tendre que crearme yo mi propio tpanel mas optimizado... Como ya comentaba utilice el tpanel porque utilizo un par de eventos de los que soporta (dbclick y el que detecta cuando esta el raton sobre el componente) por lo que con un componente exclusivamente grafico como el tshape creo que no me serviria.

Muchas gracias!

Toni 16-05-2012 10:30:00

Vaya Neftali te me has adelantado :)

Muchas gracias por la respuesta.

Es muy similar lo que prentedo realizar a las imagenes que tu pones. Mirare este componente que comentas parece bastante potente. es freeware verdad?

duilioisola 16-05-2012 17:51:06

Deberías mirar antes que nada si el problema está en crear los paneles o en calcular la gráfica que va dentro del panel.
Haz la prueba de comentar la operación que haces con el DataSet y mira cuanto tarda.

Neftali [Germán.Estévez] 17-05-2012 13:22:13

Cita:

Empezado por Toni (Mensaje 432680)
Es muy similar lo que prentedo realizar a las imagenes que tu pones. Mirare este componente que comentas parece bastante potente. es freeware verdad?

El componente es gratuíto, con código fuente y realmente muy bueno.
Todos los demás detalles en DelphiArea.

Toni 21-05-2012 09:28:40

duilioisola:

No hay ningun tiempo de calculo, es solo en crear los miles de objectos en los que tarda en crearlo. La grafica en si son los tpanel de tamaño muy pequeño. algo parecido a la imagen que puso Neftali. Gracias igualmente.

Neftali:

Muchas gracias por la respuesta. Tengo que probar a deribar mi clase de la TSimpleGraph.

Saludos,

duilioisola 21-05-2012 15:34:29

He hecho una pequeña prueba:
  • He puesto un panel y dentro de ese panel creo 2000 paneles pequeños de 9x9.
  • Esto tarda unos 20 segundos.
Luego he hecho otra prueba:
  • He puesto invisible el panel, he creado los 2000 paneles de 9x9 y lo he vuelto a hacer visible.
  • Ha tardado solo 2 o 3 segundos.
Quizás esta pseudosolución pueda ayudarte para que no tengas que rehacer tu clase.
Luego con más tiempo podrás buscar una mejor solución.

Toni 24-05-2012 11:40:45

duilioisola:

Muchas gracias por tu aporte, si con esto lo soluciono me iria perfecto ya que no tengo el tiempo para dedicarle a reestructurarlo. Aunque creo recordar que esto ya lo hacia lo de poner en invible el TGroupBox sobre el que creaba los TPanel y una vez creados lo ponia visible. Voy a revisarlo!! Gracias de nuevo!

duilioisola 24-05-2012 13:01:39

He limpiado la prueba que hice y te la envío para que puedas hacer tus pruebas.
Con 2000 paneles tarda unos 3 segundos.
Con 5000 paneles tarda unos 8 segundos.

Código Delphi [-]
unit UPruebaPanel;

interface

uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, StdCtrls, ExtCtrls;

type
   TForm1 = class(TForm)
      PNLMain: TPanel;
      PNLContenedor: TPanel;
      BCrear: TButton;
      BLiberar: TButton;
      EColumnas: TEdit;
      ELineas: TEdit;
      LCantidad: TLabel;
      procedure EColumnasChange(Sender: TObject);
      procedure BCrearClick(Sender: TObject);
      procedure BLiberarClick(Sender: TObject);
   private
      { Private declarations }
   public
      { Public declarations }
   end;

var
   Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.BCrearClick(Sender: TObject);
var
   c, l: integer;
   maxc, maxl: integer;
   p: TPanel;
begin
   maxc := StrToIntDef(EColumnas.Text, 0);
   maxl := StrToIntDef(ELineas.Text, 0);

   // Agrando el Form para que entren todos los Paneles
   Self.Width := maxc * 9 + 20;
   Self.Height := PNLMain.Height + maxl * 9 + 50;

   // Escondo el panel contenedor para acelerar el proceso
   PNLContenedor.Visible := False;

   c := 0;
   while (c < maxc) do
   begin
      l := 0;
      while (l < maxl) do
      begin
         p := TPanel.Create(PNLContenedor);
         with p do
         begin
            Name := Format('Panel_%d_%d', [c, l]);
            Parent := PNLContenedor;
            BevelInner := bvNone;
            BevelOuter := bvNone;
            Caption := '';
            Top := l * 9;
            Left := c * 9;
            Height := 9;
            Width := 9;
            // Algo para diferenciar un panel de otro
            Color := ((c + l) * $0F0F);
         end;
         LCantidad.Caption := IntToStr(maxl * c + l);
         inc(l);
      end;
      inc(c);

      // Solo refresco la pantalla por cada columna
      Application.ProcessMessages;
   end;

   // Muestro el panel contenedor
   PNLContenedor.Visible := True;
end;

procedure TForm1.BLiberarClick(Sender: TObject);
var
   i: integer;
begin
   // Escondo el panel contenedor para acelerar el proceso
   PNLContenedor.Visible := False;

   for i := PNLContenedor.ComponentCount - 1 downto 0 do
      if (PNLContenedor.Components[i] is TPanel) then
         TPanel(PNLContenedor.Components[i]).Free;

   // Muestro el panel contenedor
   PNLContenedor.Visible := True;
end;

procedure TForm1.EColumnasChange(Sender: TObject);
begin
   LCantidad.Caption := IntToStr(StrToIntDef(EColumnas.Text, 0) * StrToIntDef(ELineas.Text, 0));
end;

end.


La franja horaria es GMT +2. Ahora son las 06:21:17.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi