Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Agrupar componentes (https://www.clubdelphi.com/foros/showthread.php?t=44530)

david.rguez 08-06-2007 12:55:03

Agrupar componentes
 
Hola a todos/as:

Tenemos el Borland Delphi 2005 y nos gustaría saber si es posible agrupar lógicamente componentes.

Es decir: seleccionar una serie de componentes y formar un grupo con ellos al cuál se le da un nombre. Luego ese nombre de grupo se utilizaría en el código para dar una misma orden a todos los componentes.

Por ejemplo, agrupo los botones BitBtn1, BitBt2 y BitBtn3 en el grupo "Group1".
Y luego en el código hago "Group1.Visible:= false;", y el efecto sería que los tres botones se ocultan.

¿Es posible hacerlo en Borland Delphi 2005?

Un saludo

David Rguez.

Ñuño Martínez 08-06-2007 13:15:40

Para eso puedes utilizar Tepanel y TGroupBox. Si ocultas un panel, todos los componentes que contenga también se ocultan.

Bicho 08-06-2007 13:20:52

Hola,

no estoy seguro de que se pueda hacer eso de la manera que lo pides ni con Delphi2005 ni con ninguna otra versión.
Pero lo que si puedes hacer es lo siguiente:
- Los formularios de Delphi tienen una propiedad llamada Components. Que es una matriz con todos los componentes que hay en ese formulario.
- Tambien tienes una función llamada FindComponent que te permite buscar un componente en concreto en el formulario
- Por último puedes preguntar a un elemento de la lista de Components si ese objeto pertenece a una clase en concreto y si es así, puedes modificar sus propiedades.

Para muestra un botón:
La siguiente función recorre todos los componentes y para unas determinadas clases de objetos vacia su contenido (sean texto, labels, combos, etc.)

Código Delphi [-]
Var
  i:Integer;
begin
  With Form do
  For i := 0 to ComponentCount - 1 do
    If Components[i].Tag in Tags then
      If Components[i] is TEdit then TEdit(Components[i]).Clear
      Else
        If Components[i] is TStaticText then TStaticText(Components[i]).Caption := ''
        Else
          If Components[i] is TComboBox then TComboBox(Components[i]).ItemIndex := -1
          Else
            If Components[i] is TListView then TListView(Components[i]).Items.Clear
            Else
              If Components[i] is TMaskEdit then TMaskEdit(Components[i]).Clear
              Else
                If Components[i] is TMemo then TMemo(Components[i]).Lines.Clear
                ELSE
                  if Components[i] is TCheckBox then TCheckBox(Components[i]).Checked:=false;

Esta función afecta a todos los componentes del formulario que sean de estas clases.
Si sólo quieres que afecte a los edits del formulario y además a sólo algunos de ellos, puedes usar la función FindComponent.

Otro ejemplo: en el formulario debe haber 7 checkbox como mínimo y deben tener la nomenclatura igual: MiCheck1, MiCheck2, ...
La función busca esos checkbox y los marca.

Código Delphi [-]
var x : Integer;
begin
  if chkAll.Checked then   
    for x := 1 to 7 do (FindComponent('chk' + IntToStr(x)) as TCheckBox).Checked := True;

Bueno después de todo este rollo, espero que te pueda servir algo. Y si me he equivocado en algo, que me corrijan, y si alguien tiene alguna idea mejor...

Saludos

Bicho 08-06-2007 13:22:10

Cita:

Empezado por Ñuño Martinez
Para eso puedes utilizar Tepanel y TGroupBox. Si ocultas un panel, todos los componentes que contenga también se ocultan.

Ves más sencillo y más fácil. :p

Saludos

david.rguez 08-06-2007 13:32:06

Cita:

Empezado por Bicho
Ves más sencillo y más fácil. :p

Saludos

No, eso no me sirve (cuestión de estética del programa). No debe aparecer nada más que los componentes, sin paneles de por medio ni otros que se vean.

La idea del grupo es para, dentro de un mismo panel, poder tener distintas disposiciones manteniendo componentes sin mover, estando estos entrelazados (si pusiera un panel, los componentes fijos saldrían cortados), de forma que pueda dar una orden a todo ese grupo sin tocar el resto de los componentes que puedan estar "físicamente" entre ellos.

No sé si me doy a entender bien.

Bicho 08-06-2007 13:41:03

Cita:

Empezado por david.rguez
No, eso no me sirve (cuestión de estética del programa). No debe aparecer nada más que los componentes, sin paneles de por medio ni otros que se vean.

La idea del grupo es para, dentro de un mismo panel, poder tener distintas disposiciones manteniendo componentes sin mover, estando estos entrelazados (si pusiera un panel, los componentes fijos saldrían cortados), de forma que pueda dar una orden a todo ese grupo sin tocar el resto de los componentes que puedan estar "físicamente" entre ellos.

No sé si me doy a entender bien.

Pero los paneles puedes quitar los bordes y son totalmente inapreciables.
Así puedes tener dentre de un panel principal, varios paneles. En los cuales a uno le pones unos componentes que no quieres que se toquen y otros que lo puedes ocultar, deshabilitar, etc en otro panel.
Para ello debes modificar las siguientes propiedades:
- BevelInner = bvNone
- BevelOuter = bvNone
- BorderWidth = 0
Así el panel no se notará nada.

Creo que es lo que buscas (si lo he entendido bien)

Saludos

Ñuño Martínez 08-06-2007 13:42:02

¿Y por qué no creas una clase? Por ejemplo (así, a lo burro):
Código Delphi [-]
TGrupoComponentes = CLASS
PRIVATE
  fComponentes: ARRAY OF TCOMPONENT;
  fNumComp: INTEGER;
PUBLIC
  CONSTRUCTOR Create;
  PROCEDURE AnnadeComponente (Componente: TCOMPONENT);

  PROPERTY Componentes: ARRAY OF TCOMPONENT READ fComponentes;
END;

CONSTRUCTOR TGrupoComponentes.Create;
BEGIN
  fNumComp := 0;
END;

PROCEDURE TGrupoComponentes.AnnadeComponente (Componente: TCOMPONENT);
BEGIN
  INC (fNumComp);
  SETLENGTH (fComponentes, fNumComp);
  fComponentes[fNumComp] := Componente;  
END;
Posiblemente esto no funcione y que haya una estructura mejor que el ARRAY para almacenar referencias a componentes, pero creo que entiende la idea.

[edit] Bicho tiene razón: si quitas los bordes a un panel y le pones el mismo color que el fondo de la aplicación se vuelve invisible.

david.rguez 08-06-2007 13:51:05

Cita:

Empezado por Bicho
Pero los paneles puedes quitar los bordes y son totalmente inapreciables.
Así puedes tener dentre de un panel principal, varios paneles. En los cuales a uno le pones unos componentes que no quieres que se toquen y otros que lo puedes ocultar, deshabilitar, etc en otro panel.
Para ello debes modificar las siguientes propiedades:
- BevelInner = bvNone
- BevelOuter = bvNone
- BorderWidth = 0
Así el panel no se notará nada.

Creo que es lo que buscas (si lo he entendido bien)

Saludos

Pero el panel en sí sigue siendo visible ¿o no? Si es así, me seguiría cortando los componentes.

Código PHP:

---------                    --------- 
|   
1   |       ----------   |   3    
---------       |    
2    |  --------- 
                ---------- 

Para que os hagáis una idea. Esos son 3 componentes (botones, Edit, Grids... puede ser cualquiera). El 2 tiene que mantenerse fijo y siempre visible pero el 1 y el 3 tendrán que aparecer o desaparecer según la situación. Si utilizo un panel, aunque quite los bordes, me cortaría la mitad del componente 2, pues sigue siendo visible.

Lo que busco es poder dar una orden directa a 1 y a 3 para que se oculten (con solo 2 componentes no me importaría dar la orden uno por uno, pero cuando se juntan en mayor número toca un poco más las narices).

Bicho 08-06-2007 14:12:48

Cita:

Empezado por david.rguez
Para que os hagáis una idea. Esos son 3 componentes (botones, Edit, Grids... puede ser cualquiera). El 2 tiene que mantenerse fijo y siempre visible pero el 1 y el 3 tendrán que aparecer o desaparecer según la situación. Si utilizo un panel, aunque quite los bordes, me cortaría la mitad del componente 2, pues sigue siendo visible.

No hombre. Al panel le redimensionas como quieras o lo alineas de alguna forma y no tiene porque cortar nada.
Ves jugando con los panels. No hay necesidad de cortar objetos.

Saludos

david.rguez 08-06-2007 14:20:42

Cita:

Empezado por Bicho
No hombre. Al panel le redimensionas como quieras o lo alineas de alguna forma y no tiene porque cortar nada.
Ves jugando con los panels. No hay necesidad de cortar objetos.

Saludos

Toma como ejemplo los componentes que he "dibujado". Ahí el nº 2 se mete entre el 1 y el 3 de forma que por mucho que ajustemos el panel, pilla parte del 2 de por medio.

Y no puedo sacar el 2 de ahí porque esa es la disposición que necesito (bueno, este es solo un ejemplo, pero en nuestro programa son más componentes los que se entremezclan componiendo la ventana).

Bicho 08-06-2007 14:51:15

No hay problema.
- Pones el 1 y el 3 en un panel para ellos
- Coges el 2 y lo metes dentro de otro panel (este sin alinear, sólo que coja el tamño que quieras pero sin que pise los demas componente 1 y/o 3). Ahora mismo te quedará cortado.
- El panel que contiene el 2, en modo diseño, con el botón derecho. En el menú popup vas a la opción Control->Bring to front
- Y ya tienes el 2 encima de los demás. Ahora le quitas los bordes como te he enseñado antes y listo.

Espero ahora si te sirva.

Saludos

Lepe 08-06-2007 16:22:18

Se puede hacer por código, pero dependerá mucho de las operaciones que quieras realizar, esas operaciones tienes que definirlas de antemano, sabiendo qué propiedades quieres tocar.

Si quieres tocar la propiedad Visible nada más, podrías usar la clase Tcomponent como clase base.

El caso más peliagudo es cuando quieres tocar las propiedades que pueden existir o no (dependiendo del control).

La Forma que indica Ñuño es la más acertada, aunque sugiero un TObjectList.

Para muestra un botón:
Código Delphi [-]
uses contnrs;

Componentes:TObjectList;
begin
  Componentes := TObjectList.Create(false);
  Componentes.Add(button1);
  Componentes.Add(button2);
  Componentes.Add(Panel1);

  
for I:= 0 to Componentes.Count-1 do
  TComponent(Bottones[i]).Visible := false;
// lo que se ha añadido son botones y paneles, pero todos descienden de TComponent
// así que puedo hacer un moldeo de tipos y asignar la propiedad visible que tiene todo TComponent

  Botones.Free;
end;

Saludos


La franja horaria es GMT +2. Ahora son las 05:18:29.

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