Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Insertar Boton en StringGrid, (https://www.clubdelphi.com/foros/showthread.php?t=56317)

seb@ 14-05-2008 14:04:04

Insertar Boton en StringGrid,
 
Hola a todos!!!
Quiero agregar un boton en una celda determinada del stringgrid (el objetivo es abrir otra ventana en donde edito un memo) y no estoy pudiendo encontrar una buena solucion, si me pueden ayudar se los agradezco...

Gracias,

axesys 14-05-2008 20:19:31

Código Delphi [-]
procedure TForm1.FormCreate(Sender: TObject);
  var b:TButton;
begin
  b := TButton.Create(self);
  b.Parent := StringGrid1;
  b.BoundsRect := StringGrid1.CellRect(2,3);
  b.OnClick := Button1Click;
end;

seb@ 14-05-2008 20:44:33

Otra solucion...
 
mira no pude hacer andar el boton dentro del tstringgrid con el codigo que me enviaste, use el siguiente y anda bien, puede ser otra alternativa:
Este codigo lo utilice en el evento SelectCell del tstringgrid

Código Delphi [-]

var
  R: TRect;
begin
      // sgdWork_Sheet_Data es un tstringgrid
      R := sgdWork_Sheet_Data.CellRect(ACol, ARow);
      R.Left := R.Left + sgdWork_Sheet_Data.Left;
      R.Right := R.Right + sgdWork_Sheet_Data.Left;
      R.Top := R.Top + sgdWork_Sheet_Data.Top;
      R.Bottom := R.Bottom + sgdWork_Sheet_Data.Top;
      // btnMemo es un boton
      btnMemo.Width := 16;
      btnMemo.Left := R.Right - btnMemo.Width + 2;
      btnMemo.Top := R.Top + 2;
      btnMemo.Height := (R.Bottom) - R.Top;
 
      btnMemo.Visible := True;
      btnMemo.SetFocus;
end;

jcarlos.matrix 19-11-2008 21:07:23

Liberar la memoria
 
que sucede cuando lo agregaste el boton en el stringgrid
pero como le haces para cambiar el color del boton ya despues de
creado.

lo que hize yo fue volverloa a crear en la misma posicion pero con
otro color pero resulta que cada vez que lo hago de nuevo. la memoria usada por el programita aumenta y eso no kiero..
lo que kiero es que se libere cada vez que lo vuelvo a crear en la mismas posicion gracias.

jcarlos.matrix 17-12-2008 22:37:35

gracias. pero ya solucione el problema
 
ya pude solucionar el problema. solo tenia que hacer un destroy al boton creado y hacerle un nil despues.

ahora tengo otro problema resulta que creo varios botones pero cuando hago un resize al stringgrid se empalman los botones no hacen repaint. que hago.
gracias

rojo raton 05-10-2011 17:59:34

Hola, recientemente he estado trabajando justamente en este asunto, lástima que el hilo de sea un poco antiguo pero igual no está de más responder esa última pregunta por las dudas alguien anda tambien haciendo lo mismo.....
Bueno, suponiendo que en tu formulario tenes un StringGrid y un BitBtn (ambos creados en tiempo de diseño) para que el boton se repinte en tu stringrid agregás esas dos lineas de código en el evento OnDrawCell de ese objeto y el boton toma la forma de la celda en el caso de que el usuario modifique el tamaño de la columna o fila del stringrid.


Código Delphi [-]
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
       bitbtn1.Parent := StringGrid1;
       bitbtn1.BoundsRect:= StringGrid1.CellRect(2,3);
end;

subzero 25-01-2012 04:56:32

Hola, rojo raton gracias por exponer la forma como lo solucionaste una pregunta mas como accedes al evento click. Gracias!

rojo raton 26-01-2012 17:10:28

al ser un boton creado en tiempo de ejecución tenés que asignarle el evento onclik en tiempo de ejecución tambien.
No se muy bien como es lo que intentás hacer pero te cuento como hice mi ejemplo. Tenía una grilla con varias columnas en un formulario y quería llenar una columna con botones. Entonces puse un boton en el formulario(en tiempo de diseño) le asigné un evento onclick.
Luego, en tiempo de ejecución creé los botones que sean necesarios para rellenar la columna del grid y le asigné el evento onclick (a cada uno de ellos) del primer boton que creé al principio.

algo así..
Código Delphi [-]
begin
   b:= Tbutton.create(nil) ;
   b.Onclik:= Button1.Onclick;// le asignas el evento q vos quieras.
   b.caption:= Button1.caption;
   ...
   ...
end;

Ese ejemplo es para solo 1 boton , luego tendrás seguramente más trabajo: arrays, listobjects, etc. :D
Espero que se haya entendido algo ..

subzero 26-01-2012 17:42:18

Hola rojo raton, gracias por responder, te comento lo que quiero hacer es simple solo que no se como organizar esta parte. La idea es en una columna del stringGrid, llenarla con un boton que referencie a un evento y poder eliminar esta fila con otros procesos adicionales:

Código Delphi [-]
...
  bitbtn1.Parent := sgcodigos;
  bitbtn1.Caption:= 'Quitar'+ sgcodigos.Cells[0,sgcodigos.Row];
  bitbtn1.Onclick:= bitbtn1.Onclick;
  bitbtn1.BoundsRect:= sgcodigos.CellRect(4,sgcodigos.Row);
...

Lo mas raro es que el boton que creo en tiempo de dise;o en el onclick le tengo un ShowMEssage("Algo"), pero no me muestra nada al hacer click. Que me hace falta. Una ayudita! jejeje

rojo raton 26-01-2012 18:36:17

hay varias formas de eliminar una columna de un stringgrig.
a ver, fijate si te sirve esta:
http://www.clubdelphi.com/foros/showthread.php?t=39776

En tu caso, creo q antes de eliminarla deberías destruir los botones insertados en la columna, para que no queden en memoria, pa hacerlo más bonito digamos.

subzero 26-01-2012 23:17:25

Hola, efectivamente ya tengo la funcion para eliminar la fila y lo hace lo que quiero es colocar un boton en la ultima columna por cada fila y que al presionar dicho boton le envie un parametro a mi funcion y elimine la fila. Actualmente debo hacer doble click y luego que la informacion se carga en los edits elimino la fila.

rojo raton 27-01-2012 01:38:40

supongo que los botones insertados en la columna los ordenaste en una lista de objetos o similar (TobjectList). Ese objeto te permite saber el indice de un objeto de la lista con la función IndexOf(sender:Tobject) ; vos le mandas el boton como parametro y te devuleve su indice en la lista, y con ese indice ya tenés el numero de fila a borrar en el stringgrid.
Cuando el usuario presiona un boton en el stringgrid se dispara la siguiente función:
algo así:

Código Delphi [-]
var
  L:TobjectList;//en esta lista tendrías guardados y ordenados los botones de la columna.
procedure TForm.Button1Click(sender:TOBject);//evento del button1 creado en tiempo de diseño
var
 indice:word;
begin
    indice:= L.indexOF(sender);
    EliminarFila(indice,Stringgrid1);
end;
este evento se lo tendrás q asignar a cada botón q crees y agregues a la lista de objetos.

subzero 28-01-2012 22:48:30

rojo raton, gracias por tus aportes mi problema no esta en borrar sino en cuando se presione el boton realice el proceso, logre que lo(s) mostrara pero lo que no he podio es con el click para que usando se envie a un procedimiento o simplemente me muestre una ventana algo como un ShowMessage.... algo com insertar el evento ya he realizado un procediiento y esto es lo utlimo que hice.

Código Delphi [-]
var cont : integer;
...
while(Not EOF)do
begin
   btn := TButton.Create(nil);
   btn.Caption:= 'Quitar';
   btn.Width:= 87;
   btn.Parent:= sgcodigos;
   btn.BoundsRect:= sgcodigos.CellRect(4, cont);
   btn.OnClick := elclick;
   cont := cont + 1;
end;
.....
.....
procedure Tfproductos.elclick(Sender: TObject);
begin
   ShowMessage('Presiono Click')
end;

rojo raton 31-01-2012 05:38:44

sin embargo a mi si me funca. Mirá lo que hice:
Coloqué 2 botones comunes en un formulario vacío, cortito el programa.
Te tendría q funcionar. sino ya es otro problema.

Código Delphi [-]
var
  Form1: TForm1;
  t:tbutton;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
    t:= tbutton.Create(nil);
    t.Parent:= form1;
    t.Height:= 20;
    t.Width:= 60;
    t.Left:= 50;
    t.Top:= 50;
    t.Caption:= 'prueba';
    t.OnClick:= button2click;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
   showmessage('eureca!');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  t.Free;
end;

end.

subzero 31-01-2012 17:21:00

Efectivamente tu ejemplo funciona a la perfeccion pero sigue sin funcionarme el click de los botones incrustados en la grilla. A tu ejemplo agregue

Código Delphi [-]
procedure TForm1.FormShow(Sender: TObject);
var i : integer;
begin
  for i := 1 to 9 do
  begin
    t           := TButton.Create(nil);
    t.Caption   := 'Quitar';
    t.Width     := 87;
    t.Name      := 'BT'+IntToStr(i);
    t.Parent    := StringGrid1;
    t.BoundsRect:= StringGrid1.CellRect(4, i);
    t.OnClick:= button2click;
    StringGrid1.RowCount := StringGrid1.RowCount + 1;
  end;
end;

Alguna otra idea?

ecfisa 31-01-2012 22:58:55

Hola subzero.

Probá de este modo:
Código Delphi [-]
...
type
  TForm1 = class(TForm)
  ...
  procedure TForm1.FormShow(Sender: TObject);
  private
    procedure EventoClick(Sender: TObject);
    procedure CrearBotones(ACol: Integer);
    procedure BorrarColumna(ACol: Integer);
  public
  end;
...

implementation


procedure TForm1.EventoClick(Sender: TObject);
begin
  ShowMessage('Click en botón de StringGrid');
end;

(* Crear botones *)
procedure TForm1.CrearBotones(ACol: Integer);
var
  i: Integer;
  Btn: TButton;
begin
  for i := StringGrid1.FixedRows to StringGrid1.RowCount -1 do
  begin
    Btn           := TButton.Create(nil);
    Btn.Caption   := 'Quitar';
    Btn.Width     := 87;
    Btn.Name      := 'Button' + IntToStr(i);
    Btn.BoundsRect:= StringGrid1.CellRect(ACol, i);
    Btn.ControlStyle := [csClickEvents];
    Btn.OnClick   := EventoClick;
    Btn.Parent    := StringGrid1;
    StringGrid1.Objects[ACol,i] := Btn;
  end;
end;

(* Borrar columna *)
type
  TStringGridExt = class(Grids.TStringGrid);

procedure TForm1.BorrarColumna(ACol: Integer);
begin
  TStringGridExt(StringGrid1).DeleteColumn(ACol);
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  ...
  CrearBotones(StringGrid1.RowCount-1);
end;

...
(* Liberar botones *)
procedure TForm1.FormDestroy(Sender: TObject);
var
  i: Integer;
begin
 for i := StringGrid1.FixedRows to StringGrid1.RowCount-1 do
    StringGrid1.Objects[StringGrid1.RowCount-1, i].Free;
end;

Llamada de ejemplo:
Código Delphi [-]
procedure TForm1.btBorrarClick(Sender: TObject);
begin
  BorrarColumna(1);
end;

Un saludo.

rounin 01-02-2012 14:58:37

1 Archivos Adjunto(s)
Hola!

En principio hay la otra manera de hacer eso.
No usar las componentes, pero dibujar los
botones en células y procesar los eventos del raton y teclado.

Antiguamente he creado una pequeña librería de esto tipo basado en "FlyWeight" objetos.
(Solo uno objeto existe para todos los celulas del mismo tipo).

El adjunto contiene un ejemplo.

Casimiro Notevi 09-04-2016 10:01:28

Crea un tema nuevo con tu duda, esto no ayuda a solucionar la duda de quien creó este hilo.
No olvides nuestra guía de estilo, gracias :)
Tampoco hace falta que pongas esas letras tan grandes, podemos leer las pequeñas también :D



Cita:

Empezado por genyus00 (Mensaje 504217)
Se que a pasado tiempo... pero como se hace en este ejemplo para posicionarnos por código en un fila que queramos, no por clic en la fila.


genyus00 10-04-2016 05:01:07

Cita:

Empezado por Casimiro Notevi (Mensaje 504223)
Crea un tema nuevo con tu duda, esto no ayuda a solucionar la duda de quien creó este hilo.
No olvides nuestra guía de estilo, gracias :)
Tampoco hace falta que pongas esas letras tan grandes, podemos leer las pequeñas también :D

Para la persona que tiene la duda de como meter un botón en la stringrid, el ejemplo del .zip le va perfecto..
solo que tiene un error.

Casimiro Notevi 10-04-2016 05:09:21

Hola genyus00, es que el título de este hilo, la duda que tenía el usuario que lo creó, es "Insertar botón en stringgrid".
Debemos centrarnos en lo que ha pedido quien ha hecho la pregunta, y no contestarle algo que él no ha preguntado.
Si tú tienes una duda, debes crear un tema nuevo para que todos lo vean y puedan ayudarte.
No olvides nuestra guía de estilo, gracias :)


Cita:

Empezado por genyus00 (Mensaje 504250)
Para la persona que tiene la duda de como meter un botón en la stringrid, el ejemplo del .zip le va perfecto..
solo que tiene un error.



La franja horaria es GMT +2. Ahora son las 10:54:14.

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