Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   No muestra mi componente (https://www.clubdelphi.com/foros/showthread.php?t=8557)

Diegoval 25-03-2004 19:35:49

No muestra mi componente
 
Hola foro.

El problema que tengo es el siguiente: estoy desarrollando un componente reloj que hereda de TLabel y mustra la hora (muy facil, nada complicado), ahora el problema es cuando quiero crear dentro de este componente otro que se cree con él, por ejemplo un TPanel (solamente porque queda bonito), ahora lo que hago es lo siguiente: en el Constructor del TLabel creo el TPanel...todo bien, me compila y todo, pero cuando voy a probarlo... ¡el TPanel no aparece!. Encima también creo un TTimer que funciona perfectamente, no se mas que probar...!!!:confused:

El constructor es el siguiente:

Constructor TLabelTimer.Create(AOwner : TComponent);
Begin
inherited Create(AOwner);

pnlFondo := TPanel.Create(AOwner);
pnlFondo.Top := Self.Top;
pnlFondo.Left := Self.Left;
pnlFondo.Height := Self.Height;
pnlFondo.Width := Self.Width;
pnlFondo.Parent := Self.Parent;
end;

En estos dias estuve haciendo otro componente que también tenía que crear otro componente (en este caso era con dos TShape) y tampoco pude hacerlo, la verdad es que no se me ocurre nada...

Muchas gracias
Saludos
Diego Valcarce

andres1569 25-03-2004 20:31:54

Hola:

Prueba a poner pnlFondo.Visible := TRUE; a ver si así aparece; por cierto todos esos Self sobran, no veo que haya ningún conflicto de ámbito de variables.

Diegoval 25-03-2004 21:58:13

Asi tampoco
 
Si, eso lo probé también, pero me sigue sin aparecer, no se por qué será...

Igualmente muchas gracias...

marcoszorrilla 25-03-2004 22:12:39

Código:

El constructor es el siguiente:

Constructor TLabelTimer.Create(AOwner : TComponent);
Begin
inherited Create(AOwner);

pnlFondo := TPanel.Create(AOwner);
pnlFondo.Top := Self.Top;
pnlFondo.Left := Self.Left;
pnlFondo.Height := Self.Height;
pnlFondo.Width := Self.Width;
pnlFondo.Parent := Self;
end;

Un Saludo.

roman 25-03-2004 22:27:29

Cita:

Empezado por marcoszorrilla
Código:

pnlFondo.Parent := Self;

Me parece que no Marcos. Esta línea indicaría que la componente en sí es el 'parent'. Pero la componente es un derivado de TLabel la cual no es un contenedor.

// Saludos

__cadetill 25-03-2004 23:25:17

Cita:

Empezado por roman
Pero la componente es un derivado de TLabel la cual no es un contenedor.

Yo creo que ese es el problema, que se está intentando poner un objeto dentro de otro que no es contenedor

No obstante, esta linea

Código:

pnlFondo.Parent := Self.Parent;
hace que el padre del objeto pnlFondo sea el padre de TLabelTimer y, realmente (creo) que lo muestra, pero por debajo de TLabelTimer y por eso no se ve en pantalla

roman 25-03-2004 23:29:49

Cita:

Empezado por cadetill
hace que el padre del objeto pnlFondo sea el padre de TLabelTimer

Tienes toda la razón, las medidas y posición que se le dan al panel son exactamente las mismas que las de la etiqueta (y a decir verdad no sé cuál sea la intención de hacer esto) aunque hubiera pensado que sería la etiqueta la que se ocultaría y no alrevés :confused:

// Saludos

roman 25-03-2004 23:33:01

Je, je, cadetill. ¿Te has percatado de que la frase

"hace que el padre del objeto pnlFondo sea el padre de TLabelTimer"

tiene dos sentidos?

O el padre de TLabelTimer pasa a ser el padre de pnlFondo o el padre de pnlFondo pasa a ser el padre de TLabelTimer.

Cosas del lenguaje :)

// Saludos

__cadetill 25-03-2004 23:35:48

Cita:

Empezado por roman
O el padre de TLabelTimer pasa a ser el padre de pnlFondo o el padre de pnlFondo pasa a ser el padre de TLabelTimer.

Bueno, yo me refería a la primera opción :o

jejejejeje ;)

roman 25-03-2004 23:38:12

Cita:

Empezado por cadetill
Bueno, yo me refería a la primera opción :o

Lo sé...

ahora, porque yo me fui con la segunda opción y tuve que corregir el mensaje anterior donde te corregía.

:D

jachguate 26-03-2004 06:42:51

En todo caso, si lo que se pretende es que la etiqueta aparezca dentro del panel... yo cambiaria la herencia, de manera que el nuevo componente herede del TPanel, y en su creación se fabrique una etiqueta que mostrará la hora... o simplemente que muestre la hora en su propiedad Caption.. que es casi una etiqueta... no???

Hasta luego.

;)

Diegoval 26-03-2004 16:53:23

El problema era otro
 
Muchas gracias a todos por responderme, pero la verdad es que el problema era otro...

Todo eso que me dijeron yo lo había probado (eso de jugar con los parents) pero me lo seguia sin mostrar como mínimo, pues hasta en algunos casos hasta me tiraba error:( . Lo que dice jachguate es totalmente verdadero, el componente no sirve para nada y se podría haber hecho uno que herede de TPanel y tocar su propiedad Caption, pero el tema es que yo lo estoy haciendo mas que nada para aprender y no sabía porque no se mostraba, hasta que me mandaron una erspuesta de otro foro que me resultó:

El tema es que cuando le asigno las propiedades de Self.Top, Self.Left, etc. estas propiedades todavía no tienen un valor (ya que el componente se esta creando), solamente por eso es que no se mostraba, ya lo corregí y ahora funciona perfectamente...:p

Igualmente muchisimas gracias a todos, nuevamente.

delphi.com.ar 26-03-2004 17:11:44

Me parece que estas cometiendo un error al hacer:
Código:

pnlFondo.Top := Self.Top;
pnlFondo.Left := Self.Left;
pnlFondo.Height := Self.Height;
pnlFondo.Width := Self.Width;

Posiblemente lo que quieras hacer es:
Código:

pnlFondo.Top := 0;
pnlFondo.Left := 0;
pnlFondo.Height := Self.Height;
pnlFondo.Width := Self.Width;

Recuerda que este componente esta contenido por el Self.

Otra opción puede ser trabajar con BoundsRect y ClientRect o con la propiedad Align := alClient!

Saludos!

roman 26-03-2004 17:40:27

Cita:

Empezado por delphi.com.ar
Recuerda que este componente esta contenido por el Self.

¡Pero de aquí parte la confusión! No puede estar contenido en Self ya que Self es un derivado de TLabel y TLabel no es un contenedor. Quizá redefiniendo ValidateContainer pero realmente dudo que tal sea la intención, ¡¿un panel dentro de un label!??

// Saludos

delphi.com.ar 26-03-2004 17:43:22

Cita:

Empezado por roman
¡Pero de aquí parte la confusión! No puede estar contenido en Self ya que Self es un derivado de TLabel y TLabel no es un contenedor. Quizá redefiniendo ValidateContainer pero realmente dudo que tal sea la intención, ¡¿un panel dentro de un label!??

Eso me pasa por no haber leído todo el hilo, mismo ahora me doy cuenta que ya lo solucionó! :D

Saludos!

roman 26-03-2004 17:58:54

Cita:

Empezado por delphi.com.ar
Eso me pasa por no haber leído todo el hilo, mismo ahora me doy cuenta que ya lo solucionó! :D

¡Vaya! Pues yo ahora me doy cuenta de esto. Juro que al dar click en "Ir al primer mensaje nuevo" me llevó al tuyo y no al de él. :(

De cualquier manera ya haré la prueba pues realmente me intriga ver qué aspecto tiene una cosa así.

Para Diegoval que dijo:

Cita:

Empezado por Diegoval
ya lo corregí y ahora funciona perfectamente

¿Y te importaría corresponder a la ayuda exponiendo la solución?

// Saludos

Diegoval 26-03-2004 20:30:17

Ahora entiendo menos...
 
El tema es el siguiente:

El ejemplo que yo puse (un TLabel con un TPanel) es medio tonto y la verdad es que por si no funciona para nada... pero me sierve para probar como hacer para crear un componente visual dentro de otro tambien visual... por ejemplo...

Yo quiero hacer un componente que represente un cuadrado dentro de otro y luego unir los vertices superior izuierdo del mas grande con un superior izquierdo del mas chico y asi...(lo que simularía un diente en la planilla odontológica) para despues capturar el mensaje click y hacer lo que corresponda segun en que area del diente clickee... ahora viene el problema de cómo hacerlo.
A mi se me ocurrio heredar de un TShape y luego crear otro TShape para ponerlo dentro y luego hacer las lineas que unan los vértices. Bueno, el tema es que se cómo hacer para crear un componente desde otro componente, o sea, la pregunta sería como hacer para hacer eso?

Lo anterior (del componente TLabel y el TPanel) lo solucioné asignando las propiedades Left, Top, etc. del panel en el evento Paint del Label y no en el Create. (Igualmente no me funcionó del todo bien, seguramente no se debe hacer asi...)

La verdad me parece tan sencillo que no se por qué no me sale, pero tampoco se me ocurren soluciones alternativas para crear un diente...!!!

roman 26-03-2004 20:44:05

Permíteme hacerte unos comentarios:

De verdad me parece estupendo que desees aprender y siempre es útil trabajar a prueba y error- a veces no queda más remedio. Pero también es muy recomendable que se tome uno un tiempo alejado del ordenador para leer la documentación.

En tu caso, ya que deseas escribir componentes te recomiendo que leas el apartado Component Writer's Guide. No se trata de que lo entiendas todo de una sóla vez pero sí de que te des una idea del tipo de cosas que se involucran.

Por ejemplo, encontrarás ahí la información acerca del método Loaded, que sirve precisamente para inicializar valores que dependen de que las propiedades de la componente ya estén cargadas.

Asímismo te darás una idea general de que son los controles contenedores y porque entonces no es una buena idea tratar de meter una componente en un TLabel.

// Saludos

__cadetill 26-03-2004 21:10:31

Solo añadir a lo que comenta Román, que también sería bueno que mirases en Google y buscases "curso de creación de componentes". Te saldrán cantidad de enlaces interesantes.

Uno de los que más me ha gustado (no los he mirado todos) es este , un documento en PDF de 105 páginas ;)

Al González 28-03-2004 04:15:48

Cita:

Empezado por Diegoval
...cuando le asigno las propiedades de Self.Top, Self.Left, etc. estas propiedades todavía no tienen un valor (ya que el componente se esta creando), solamente por eso es que no se mostraba...

Tienes razón :). Al llamar al constructor heredado:
Código:

Constructor TLabelTimer.Create(AOwner : TComponent);
Begin
inherited Create(AOwner);

se inicializa el objeto etiqueta a Left = 0, Top = 0, Width = 65 y Height = 17:
Código:

constructor TCustomLabel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := ControlStyle + [csReplicatable];
  Width := 65;
  Height := 17;
...

Por lo cual, el objeto TPanel toma las dimensiones iniciales de la etiqueta. Sin embargo, la sentencia
Código:

pnlFondo.Parent := Self.Parent;
le asigna un valor de Nil a la propiedad Parent del objeto TPanel, debido a que en ese momento Selft.Parent (o simplemente "Parent"), es decir, la propiedad Parent de la etiqueta, aún no tiene valor asignado. Si tal etiqueta es un control agregado a una forma en tiempo de diseño, entonces será hasta que el componente se cargue, cuando le sea asignado un valor (esto es después de la construcción).


Cita:

Empezado por roman
...te darás una idea general de que son los controles contenedores y porque entonces no es una buena idea tratar de meter una componente en un TLabel...

De hecho Diegoval no pretendía meter el objeto panel dentro del objeto etiqueta. Sólo los objetos derivados de TWinControl (TLabel no lo es) son asignables a la propiedad Parent de los componentes controles (derivados de TControl).


¡Hasta pronto!

Al González :).

Los negocios se deben ajustar a las capacidades humanas, no las capacidades humanas a los negocios. Por una vida laboral sana ;).


La franja horaria es GMT +2. Ahora son las 08:32:59.

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