Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Como saber cuando se hace click sobre uno de los 120 Tpanel (https://www.clubdelphi.com/foros/showthread.php?t=60191)

Nebli 23-09-2008 22:30:42

Como saber cuando se hace click sobre uno de los 120 Tpanel
 
Hola a tod@s.

La pregunta es sencilla, pero despues de estar probando lo poco que sé no he encontrado la respuesta, por eso pido ayuda.

Tengo un total de 120 Tpanel en una Form, y necesito saber cuando se hace 'click' sobre uno en concreto de ello. No es sentato poner 120 eventos OnClick, uno para cada Tpanel, por lo que he tratado de capturar el TPanel utilizando la matriz de componentes y comprobando cual de ellos tenía el foco, pero parece ser que como los Tpanel no admiten el foco, no lo puedo detectar.

Agradecería la ayuda de quien me pueda decir una forma de saber sobre cual de ellos se hace 'click' con el ratón.

Me he propuesto hacer un programa que llevo intentando hacer hacer varios años, y que como no hay tiempo ni para rascarse aún no lo había empezado. Ahora me he propuesto dedicarle unas horas los fines de semana y con los años espero terminarlo, porque creo que no va a ser nada sencillo.

A quien me pueda ayudar, le doy las gracias anticipadamente.

Gracias anticipadas

droguerman 23-09-2008 22:40:05

puedes asignar un mismo evento a todos los paneles y usar la propiedad tag para saber que panel fue el que pulsaste algo así:
Código Delphi [-]
procedure TPanel_Click(sender : TObject);
var
  nro : integer;
begin
  nro := TPanel(sender).tag;
end;

DarkMan 23-09-2008 23:24:33

Puedes usar el parámetro sender para acceder al panel sobre el que se hace el click. Todos los paneles pueden tener asociado el mismo evento:
Código Delphi [-]
 
Procedure TPanelclick( Sender: TObject );
begin
 (Sender as TPanel).Caption := 'Seleccionado';
end;

Nebli 24-09-2008 09:00:36

Os agradezco a los dos vuestra ayuda, gracias a ello he podido continuar con lo que estoy programando.

Un saludo y muchas gracias de nuevo.

Nebli 24-09-2008 09:11:01

Lo que voy a hacer es lo siguiente:

// con esto se el nombre del Tpanel sobre el que se ha hecho click
textop := (Sender As Tpanel).Name;

Le quito al contenido de 'textop' la palabra 'Panel' ya que cada Tpanel se llama Panel1, Panel2, ect. con lo que sólo me quedará el número del Tpanel seleccionado, que irá desde el 1 al 120.

Una vez tengo el número del Tpanel selccionado, podré saber la columna y la fila en la que está en la ficha, ya que he puesto 12 Tpanel por fila y tengo 10 filas.

Gracias.

- por si hay curiosidad por saber de qué va la historia:
Hace varios años me propuse crear un programa para jugar a las 4 en raya contra el ordenador, con la salvedad de que el ordenador no sabrá casi nada cuando haga la primera partida y tendrá que ir aprendiendo conforme vaya juando. La idea creo que es demasiado ambiciosa, sobre todo porque no tengo tiempo ni de rascarme, pero me he propuesto los fines de semana dedicarle unas horas, y así hasta que lo termine. No tiene fecha de término de momento.

Lepe 24-09-2008 11:24:26

Ya que te has explicado mejor, te recomiendo usar Frames, es como si crearas un panel pero con las propiedades que tu quieras, en este caso, puedes añadirle dos propiedades Fila y columna, de esa forma no tienes que hacer virguerías para averiguarlo, solo tienes que consultar esas 2 propiedades (que obviamente habrás asignado cuando creas el frame).

Como ejemplo didáctico, este calendario con frames dinámico

En lugar de 120 paneles, tendrás 120 frames.

Saludos

ContraVeneno 24-09-2008 14:35:53

Cita:

Empezado por Nebli (Mensaje 315905)
Lo que voy a hacer es lo siguiente:

// con esto se el nombre del Tpanel sobre el que se ha hecho click
textop := (Sender As Tpanel).Name;

Le quito al contenido de 'textop' la palabra 'Panel' ya que cada Tpanel se llama Panel1, Panel2, ect. con lo que sólo me quedará el número del Tpanel seleccionado, que irá desde el 1 al 120.

¿para que tanto relajo con editar el nombre, quitarle el inicio, convertir el final a entero, etc, etc, cuando puedes utilizar la propiedad TAG como te recomendaron al principio?

Número := (Sender As Tpanel).Tag;

gatosoft 24-09-2008 23:59:35

Hola a todos...

Estaba pensando que tan correcto era manejar 120 paneles o frames en una pantalla... es obvio que la situación amerita que existan, pero cual de los dos es mas eficiente en cuanto al manejo de memoria...

Podríamos decir que las maquinas de hoy lo aguantan todo... pero ese es un pensamiento muy "Gates"... Consumir todos los recursos porque para eso hay suficiente....

Que tal por ejemplo un TSahpe ? cual consume mas recursos? como medirlo?

Que tal una Grilla?

Por que 120 TButons? (jejejeje)

Que tal dibujar la cuadricula en el canvas del form y (con mas codigo) evaluar las posiciones del raton y sus eventos...?

Lo digo por que yo he tenido que enfrentar esta situacion mas de una vez y siempre me queda la inquietud de si he utilizado la mejor estrategia....

Por comodidad he termindao usando un TStringrid para manejar este tipo de situaciones (mientras se pueda)...

Saludos,

ContraVeneno 25-09-2008 14:36:13

lo mismo dije una vez cuando alguien estaba utilizando creo eran 130 TEdits en un solo formulario... lo que dije fue: "Cuando utilizas más de 20 controles del mismo en un solo formulario, entonces tienes un problema muy grande de diseño..."

pero creo que mi comentario les molestó o algo, por eso ya no lo quise volver a decir...

en fin, 120 paneles para mi es un problema muy grande de diseño.

Nebli 26-09-2008 15:40:57

Hola a tod@s y gracias por vuestras sugerencias.

Debido a mi escaso conocimiento de Delphi, no me quiero meter en temas como si utilizo más recursos o menos del ordenador, pido disculpas a quien considere que hay que hacer las cosas de otra forma, pero tengo dos problemas importantes: 1) Que no tengo el tiempo que me gustaría dedicarle a Delphi para aprender más a fondo y 2) que esto me lo he tomado como algo de 'distracción' para salir un poco del 'siempro llego tarde a todo', es decir, los fines de semana, si puedo, le dedicaré unas horas e hiré haciendo poco a poco el programa, ya dije que no le he puesto fecha de terminación. Lo mismo pasan 2 años y todavía no le he terminado.

Sobre lo de utilizar la propiedad Tag lo he pensado una vez me lo comentastéis, pero para ello, ya que nos ponemos, lo suyo es hacer los Tpanel en tiempo de ejecución, y que los dibuje el propio progama al empezar y con ello que asigne los nombres a los Tpanel y el número que correspnda a la propiedad Tag.

Como me tenía que complicar más en crear nuevo código para dibujar los Tpanel, calcular el sítio donde ponerlo para hacer las filas y así sucesivamente, al final pensé que el trabajo entre esto y poner los Tpanel en tiempo de diseño se llevaría muy poco o tardaría menos en tiempo de diseño, lo que hice fue ponerlos en la ficha directamente, para ello, puse los 12 de la primera fila y luego la copie y la pegué otras 9 veces y ya estaba terminado. De esta forma, si quiero utilizar la propiedad Tag, sí le tengo que asignar el número a la propiedad Tag, y tendría que ir uno por uno metiéndome en dicha propiedad y ponerle dicho número de orden. Al final pensé que era más rápido averiguar qué Tpanel se seleccionaba y como cada uno tiene un nombre que va del 1 al 120 ya estaba, sólo hay que quitar lo que se repite siempre en el nombre y nos queda el número de orden, que con un IntToStr() nos dá el número de orden del Tpanel.

Por otro lado, ya que me pongo, me gustaría hacer como vi en un ordenador hace mucho tiempo, y es no limitarme al espacio de la pantalla, es decir, que si en la partida que estamos se llena la pantalla o antes de eso queremos poner en una fila o más hacia arriba o hacia abajo de lo que se está viendo, que podamos hacerlo, esto es, aunque en la pantalla tengamos 120 posiciones posibles, realmente tengo previsto ponerle 500 x 500 posiciones, y centrar el juego en esa cuadrícula, así si se quieren ir hacia la izquierda o derecha, o hacia arriba o hacia abajo se pueda mover el tablero.

Repito que en este momento el problema de los recursos, para mi caso y con mis conocimientos, lo paso a segundo plano, lo que me gustaría ver algún día es que mi propio programa me lo pone difícil para que le gane. ¡ Sería una pasada !

La ilusión no la debemos perder.

De nuevo muchas gracias a todos por vuestras sugerencias. Os agradezco sinceramente la ayuda que prestáis a los que somos bastante novatos en esto.

gatosoft 26-09-2008 18:05:04

Hey amigo Nebli... No, a mi no me incomoda el hecho que hagas tu aplicacion asi..... Yo solo comentaba que ya muchos hemos pasado por ahi y hemos tenido el mismo dilema....

Bueno por otro lado, si me da un tick en el ojo cuando veo que prefieres hacer el trabajo en tiempo de diseño.... Es cierto que te toca escrbir un poco mas de codigo, pero no es tanto y compensa a la hora de hacer el mantenimiento a tu codigo.... como tu mismo observas... si quieres hacer una matriz de 500 x 500 vas a tener probelmas mas adelante....

Te envio un codigo de base para que lo revises ... a lo mejor te sirve...

1) Abre un proyecto nuevo
2) pon un Boton en el formulario
3) has dobleclick sobre el boton (Se crea el evento onclick pero no hagas nada con eso)
4) sobre-escribe todo este codigo en tu Unit1...

Espero que te sirva

Código Delphi [-]
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    //Debes crear tu evento Onclick... Definido de la siguiente manera   
    //type TNotifyEvent = procedure (Sender: TObject) of object;
    Procedure MyOnClick(Sender: TObject);
    procedure ConstruirPaneles(objContenedor_p:TWinControl; intFilas_p, intColumnas_p:Integer);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ConstruirPaneles(objContenedor_p:TWinControl; intFilas_p, intColumnas_p:Integer);
Var ElPanel:TPanel;
    i,j,
    intContador,
    intAncho,
    intAlto,
    intSeparacionFilas,
    intSeparacionColumnas,
    intMargenFilas,
    intMargenColumnas:Integer;
Begin

   //Valores en Pixeles
   //Juega con ellos para que veas el efecto
   intAncho:=40;
   intAlto:=40;
   intSeparacionFilas:=5;
   intSeparacionColumnas:=5;
   intMargenFilas:=50;
   intMargenColumnas:=50;

   intContador:=0; //Para manejar el Tag

   For i:=1 to intFilas_p do
     For j:=1 to intColumnas_p do
     Begin
        inc(intContador);

        ElPanel:=TPanel.Create(objContenedor_p);
        ElPanel.Name:='MyPanel_'+IntTostr(intContador);
        ElPanel.Tag:=intContador;
        ElPanel.Caption:=IntToStr(intContador);
        ElPanel.OnClick:= MyOnClick; //Asignas tu evento al evento de cada panel que crees

        ElPanel.Width:=intAncho;
        ElPanel.Height:=intAlto;
        ElPanel.Top:=(i-1) * (intAlto+intSeparacionFilas) + intMargenFilas;
        ElPanel.Left:=(j-1) * (intAncho+intSeparacionColumnas) + intMargenColumnas;
        ElPanel.Parent:=objContenedor_p;
     end;// for j
end;

Procedure TForm1.MyOnClick(Sender: TObject);
Begin
  ShowMessage('Clickeaste en el panel: '+(Sender as TPanel).Caption);
  //Pon aqui el codigo que quieras... por ejemplo para dar color a tus paneles
  //Bueno aqui utilizars el tag para algo....
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ConstruirPaneles(Self,10,12);
end;

end.

Bye

Nebli 26-09-2008 21:28:23

Hola gatosoft.

Te agradezco el código que me has enviado, lo he probado y va de cine. Puedes cambiar el ancho, el alto, la situación a un origen, etc. de los Tpanel. La verdad es que muy bien. Además te sale el nombre del Tpanel en el centro del mismo para confirmar que te indica el que realmente has pulsado.

El problema que tengo es que hay variables no llego a entender del código que me envías y si lo tengo que hacer eso yo seguro que me hubiese costado bastante más que te habrá costado a tí, ya que tendría que haber sacado el libro gorto de 'Petete' que diga de Delphi, buscar y ver como hacerlo.

Además como le asignas ya al crear los Tpanel a Tag un número, ya lo tienes todo solucionado.

¡¡ Pero no funciona !!

¡¡ Es una broma !! como dice mi hijo. Al pulsar dos veces sobre el botón como intenta crear de nuevo un Tpanel con el mismo nombre que una ya existente da error. Pero lo que tu me envías es un ejemplo, no se trata de ver si da ese error.

Gracias por todo. Lo he guardado en una carpeta dentro de los programas de Delphi para si es necesario utilizarlo.

Un saludo.


La franja horaria es GMT +2. Ahora son las 19:15:10.

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