Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 17-09-2004
keglevich keglevich is offline
Registrado
 
Registrado: oct 2003
Posts: 9
Poder: 0
keglevich Va por buen camino
Comunicación entre unidades

Al grano:

2 unidades: unit1, unit2
unit1: Declaración e implementación de todas las clases que usaré en unit2. No tiene formulario.
unit2: Con su formulario, lugar donde se desarrollará la ejecución de la aplicación.
UNIT1
Código:
 miclase=class
    private
       nombre:String;
       imagen:TImagen;
       procedure _imagenClick(Sender:TObject);
   (...)
Ahora en unit2, hago el
Código:
uses unit1;
,
creo un objeto de esa clase, y quiero que cuando haga click sobre la imagen que lo representa (ya creada y tal en el constructor), se me muestre el valor de la variable nombre, convertida en propiedad, o accedida a traves de un método me da igual, en algún componente del formulario, un TEdit por ejemplo.
Mi problema es que no se como hacer que en unit2se detecte que he hecho click sobre esa imagen, identificandola, porque habrá mas objetos con sus correspondientes imágenes por allí.
Claro si declaro/implemento esa clase en unit2 podré acceder a todos los componentes que están en ella, y ya podré mostrar información, crear menús contextuales haciendo click con el botón derecho sobre la imagen y demás tonteridars....pero queda un poco-mucho cutre...
Pido perdón de antemano porque es la primera vez que uso las etiquetas...y no se como van a salir...
MUCHAS GRACIASESESESSSS
Responder Con Cita
  #2  
Antiguo 17-09-2004
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Unas preguntas, ya que no acabo de comprender bien lo que explicas.

¿Cada imagen del form tiene un objeto de la clase miClase asociado?
¿El objeto de tipo TImage de la clase es el mismo que el formulario?
¿Cómo "enganchas" cada objeto de la clase miclase con un TImage del form?

¿Exactamente cual es el cometido de esa clase? Lo digo porque si sólo es almacenar esos datos, o realizar operaciones sobre los componentes visuales TImage, sería más correcto, derivar el control TImage y añadirle las propiedades/eventos que necesites.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 17-09-2004
keglevich keglevich is offline
Registrado
 
Registrado: oct 2003
Posts: 9
Poder: 0
keglevich Va por buen camino
Tratando de aclarar....

Hola Neftali, a ver si puedo hacer que entiendas lo que tengo montao y lo que quiero hacer...
miclase guarda mucha información, es decir, tiene un estado abundante, y esa información se crea/modifica desde el form. El hecho de meter una imagen en miclase es para tener una representación gráfica del objeto en el form. Éste ( el objeto ) puede cambiar tanto "geofráficamente", como bien me explicaste con el ratón, como los datos que contiene, modificandolos.
Lo que necestio ahora es hacer click encima de la imagen que representa ese objeto, presentar la información contenida en el, y dar la opción de poder modificarla, ya sea a traves de un menú contextual , que te lleva a otro form, o mediante la presenstación de la info en algún contenedor en ese form para poder ser editada insitu....arf arf

¿Cada imagen del form tiene un objeto de la clase miClase asociado?
No, hay imágenes que no tienen que ver nada con los objetos de miclase, de hecho, las imágenes que referencian a los objetos de miclase van sobre otra imagen que es una rejilla cuadriculada.


Ahora tengo que irme ...pero cuando vuelva termino el comentario..
(...)

GRACIAS!
Responder Con Cita
  #4  
Antiguo 17-09-2004
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Me parece bastante confuso tu mensaje. Sin embargo, puedo echarte un cable. Basate en las propias ideas ya desarrolladas por la gente de borland.

Si tu clase tiene una parte visual y puede ser colocada sobre un formulario, quizas debiera ser un componente.

Si cada instancia de la clase, además de ser representada por la imagen, siempre va a necesitar de una label o de un edit, entonces, crealos al igual que creas la imagen. Si por el contrario, tu objeto no puede o no debe ser el owner, usa propiedades que le enlacen con otros componentes de la forma. Por ejemplo, una propiedad Editor de tipo TEdit, que es un apuntador a un Edit cualquiera. Asi, el programador final, via inspector de objetos, o via código, puede enlazarle con el edit de su preferencia (o dejarle sin enlace).

Cuando te haga falta notificar algún cambio o situación a la forma que contiene al objeto o componente de tu autoria, crea un evento, y deja que el programador de la forma decida por último si atenderlo o no, y que hacer al respecto.

No hay ninguna regla que impida que el programador final seas vos mismo, pero es mejor que separes psicológicamente las funciones de "bibliotecario" o "programador de componentes", con "programador de aplicaciones"... de esa forma conseguiras una implementación mas robusta.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #5  
Antiguo 18-09-2004
keglevich keglevich is offline
Registrado
 
Registrado: oct 2003
Posts: 9
Poder: 0
keglevich Va por buen camino
Question Concretando el problema

Ante todo muchas gracias por vuestro consejo y esfuerzo.
Voy a intentar concretar el tema...
No se si lo que quiero hacer se puede hacer si crearte tu propio componente y tus propios eventos. Sospecho que si, así que intentaré explicarme con mas claridad metiendo mas código de por medio
No pondré las clases que uso porque son un poco coñazo y largas, así que extrapolaré algo que mas o menos sea equiavlente pero resumido:

Código:
unit unit1;

TDibujo = class

private
 nombre:String;
 x,y:single;
 radio:single;
 imagen:TImage;
 procedure _Onclick(Sender:TObject);

constructor    Create(nombre:String;cx,cy,radio:single;im:String;padre:TWinControl);
 (...)

end;


implementation
 
 constructor  
  TDibujo.create(nombre:String;cx,cy,rad:single;im:String;padre:TWinControl);

   begin
    x:=cx;
    y:=cy;
    radio:rad;
     imagen:=TImage.Create(nil);
     imagen.Parent:=padre;
     imagen.Picture.Bitmap.PixelFormat:=pf24bit;
     imagen.OnClick:=_imagenclick;
     if radio<10 then
      imagen.Picture.LoadFromFile('pequeño.bmp')
     else
      imagen.Picture.LoadFromFile('grande.bmp');

   end;

(...)

 procedure _OnClick(Sender:TObject);
  begin
   ?¿?¿?¿?
  end;

IDEA - OBJETIVO

En el form de la unit2 habrán:

-boton CREAR: que cada vez que se pulse, creará un objeto de tipo TDIbujo. La imagen se presentará en el form según las coordenadas que se le asignaron al objeto al crearlo ( por ejemplo de forma aleatoria ). Claro,¿no? :P

- 4 Componentes tipo TEdit, vacios, en la parte inferior del form, con sus TLabels: "nombre, coordenada X, coordenada Y, Radio".

Así tendré tantas imágenes en el form como objetos creados de TDibujo.
Estas imágenes que representan a los objetos de TDibujo, se pueden mover con el ratón, es decir, pinchando sobre una y arrastrandola donde quieras. Las coordenadas de donde sueltes la imagen, deben actualizarse en el objeto. ESTO LO TENGO RESUELTO GRACIAS A NEFTALI .

EL PROBLEMA
Tambien quiero que cuando hagas un click sobre cualquier imagen, en los TEdit aparezca los datos del objeto que representa esa imagen. Se entiende ¿no?. Hago click sobre una imagen, y aparece su nombre, coordenadas, y radio en los TEdit del formulario.

LA SOLUCIÓN CUTRE
Si declaro/implemento la clase TDibujo en la unit2 podría implementar así:

Código:
 procedure TDibujo._OnClick(Sender:TObject);
  begin
   TEditNombre.text:=nombre;
   TEditcX.text:=FloatToStr(x);
   TEditcY.text:=FloatToStr(y);
   TEditRadio:=FloatToStr(radio);
  end;
Lo puedo hacer así ya que los componentes TEdit están en el mismo formulario que la (definición de la) clase y son visibles a ella(a la clase), pudiendo así acceder sin problemas.
Pero esta solución me parece muy poco elegante, aparte de otras cosas.

EL PROBLEMA (AMPLIACIÓN)

Como la clase está en la unit1, y en la unit2 empiezo así:
Código:
 unit unit2

  uses unit1;
NO PUEDO ACCEDER A LOS COMPONENTES DE LA unit2 DESDE LA unit1, es decir:

Código:
 procedure TDibujo. _OnClick(Sender:TObject);
  begin
   unit2.TEditNombre.text:=nombre;
   (...)
...me dice que no sabe quien sea unit2, porque no la usa, y no puede usarla porque crearia un "circular unit reference".
Cuando hago un click sobre la imagen, capturo el evento, pero tengo que codificarlo en la unit1, y por lo tanto no puedo acceder a los componentes de la unit2 para mostrar los datos del objeto....arf arf.
Espero que ahora se entienda bien mi problema :P.

La idea de jachguate de crearme mi propio componente y mis propios eventos, me parece buena....pero mis conocimientos no llegan a tanto... Y por ahora no tengo demasiado tiempo para aprenderlo, aunque lo haré en un futuro ya que ya veo que es bastante útil.

Creo que no se me olvida nada....de todos modos ¡¡¡MUCHAS GRACIAS POR VUESTRA AYUDA!!!

Editado por jachguate. razon: sacar de la etiqueta code lo que no debia estar alli:

Última edición por jachguate fecha: 18-09-2004 a las 01:11:18.
Responder Con Cita
  #6  
Antiguo 18-09-2004
Mick Mick is offline
Miembro
 
Registrado: may 2003
Posts: 405
Poder: 21
Mick Va por buen camino
Para evitar referencias circulares debes poner uno de los uses en la zona "implementation" de la unit y no en la de "interface".

A pesar de que se pueda resolver el problema del modo indicado, en general, salvo casos excepcionales, el tener referencias circulares suele significar que el diseño del programa no es correcto.

El uso de clases precisamente se utiliza para "encapsular" los datos y el codigo de modo que unas clases sean lo mas independientes posibles de otras. Por ejemplo los componentes que visuales que vienen de serie con delphi , no necesitan tener un uses en sus units que hagan referencia a las unidades y forms que creas en tus programas, pero perfectamente se pueden insertar dentro de tus forms.

El tema que propones es demasiado extenso y general como para resolverlo en un post del foro, busca en google por tutoriales para creacion de componentes en delphi (quizas en esta misma web haya alguno).

Saludos
Miguel
Responder Con Cita
  #7  
Antiguo 18-09-2004
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Cool

Hola.

Como ya te ha dicho miguel, lo que te hace falta es leer un buen manual, libro o tutorial de creación de componentes.

Basta con que uses una de las técnicas ya descritas por mi, por ejemplo los apuntadores.

Te diré de manera rápida una forma general de solucionarlo, sin pretender que esto se vuelva un curso de POO o de componentes.

Código Delphi [-]
Type
  TmiClase = class(TComponent)
  private
    FLabel : TLabel;  //este es un apuntador a un label, donde podremos
                 // publicar algun dato.  Este label normalmente será parte de
                 // la forma que use el componente.
    Procedure SetLabel(value : TLabel);
    Procedure Notification(AComponent : TComponent; Operation : TOperation); override;
  public
    Procedure HacerAlgo;
    Property Label : TLabel read FLabel write SetLabel;  
  // Publicación de la propiedad. Si queres que se vea en el inspector de 
  // objetos, pasala a la seccion published.  En este hipotetico caso, 
  // el componente no se usará en tiempo de diseño, por lo que no hace 
  // falta.
  end;

implementation

Procedure TMiClase.SetLabel(value : TLabel);

Begin
  FLabel := value;
  if assigned(FLabel) Then
    FLabel.FreeNotification(Self);
  // esto es para que el componente notifique si se destruye, a manera de no
  // conservar referencias a objetos que no existen, lo que provocaria un GPF
end;

Procedure TMiClase.Notification(AComponent : TComponent; Operation : TOperation); 

Begin
  if (operation = opRemove) and (AComponent = FLabel) Then
    FLabel := nil;
  // liberamos la referencia
end;

Procedure TMiClase.HacerAlgo;

Begin
  if assigned(FLabel) Then
    FLabel.Caption := 'Hola';
  // mostramos algo en el label, que estará en la forma que use el
  // componente, e incluso en otra forma.
end;

// ahora el componente se crearia algo asi:

Procedure TForm1.Button1Click(sender : TObject);

Var
  newComponent : TMiComponente;

Begin
  newComponent := TMiComponente.Create;
  newComponent.Label := Label1;
  newComponent.HacerAlgo;
end;

Lamento que las explicaciones sean escuetas, espero que el código se explique por si mismo. He tratado de aclarar con comentarios los puntos que pueden parecerte cripticos.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #8  
Antiguo 18-09-2004
[basti] basti is offline
Miembro Premium
 
Registrado: ago 2004
Posts: 388
Poder: 20
basti Va por buen camino
Creo que la solución más sencilla en tu caso es declarar el procedimiento _OnClick en Unit2, y no dentro de la clase TDibujo.

Así después de llamar al constructor de la clase TDibujo, puedes asignarle al evento OnClick de la clase TImage tu propio _OnClick.

Después para identificar el objeto con el que trabajas, podrías utilizar la propiedad Tag del TImage, asignando un valor distinto para cada imagen.
Responder Con Cita
  #9  
Antiguo 19-09-2004
keglevich keglevich is offline
Registrado
 
Registrado: oct 2003
Posts: 9
Poder: 0
keglevich Va por buen camino
Gracias A Todos

Al final he hecho lo que me aconsejaba Basti y ha funcionado a las mil maravillas, ¡¡MUCHAS GRACIAS TIO!!.
De todos modos me apunto para cuando tenga un poco de tiempo lo de aprender a crear mis propios componentes, que ya veo que es fundamental en cuanto profundizas un poco. El ejemplo que me mandaste, JachGuate me ha picado la curiosidad bastante, y me parece muy interesante...ya me estoy buscando algo parar aprender :P
Lo dicho..

¡¡¡GRACIAS A TODOS, Y HASTA LA PRÓXIMA DUDA!!!

Responder Con Cita
  #10  
Antiguo 20-09-2004
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Estoy de acuerdo en que la solución adoptada sea la más sencilla, pero creo que la más correcta y "limpia" sería un componente visual creado a partir de TImage; Con eso casi tendrías el problema resuelto sólo, y a madidas que las cosas se compliquen lo tendrás todo más sencillo.
También entiendo que a veces no hay tiempo para hacer todo lo que a uno le gustaría y hay que "tirar por el camino más recto".
Te aconsejo que cuando tengas un rato lo pruebes (a derivar TImage) ya que no es tan complicado como parace y te ayudará a comprender muchas cosas... y si tienes algun problema ya sabes donde estamos...
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 22:07:29.


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
Copyright 1996-2007 Club Delphi