Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   TPageControl en tiempo de ejecución (https://www.clubdelphi.com/foros/showthread.php?t=7823)

esocrates 27-02-2004 04:05:02

TPageControl en tiempo de ejecución
 
Estoy experimentando con un editor de textos con un TPageControl con la idea de poder tener disponibles varios archivos simultáneamente cada uno con su respectiva solapa. Cada TTabSheet contiene un Memo.
No consigo crear un nuevo TTabSheet en el TPageControl en tiempo de ejecución [para crear un nuevo archivo]. En el evento click [Archivo nuevo... ] intento con este código sin respuesta alguna.
Código:

TTabSheet.Create(PageControl1);
Les agradeceré me orienten .
Muchas gracias y hasta pronto

roman 27-02-2004 04:46:37

Debes asignar PageControl1 a la propiedad PageControl del TabSheet recién creado.

// Saludos

esocrates 27-02-2004 15:23:59

Cita:

Empezado por roman
Debes asignar PageControl1 a la propiedad PageControl del TabSheet recién creado.

// Saludos

Gracias por la respuesta.
Efectivamente con esta indicación he conseguido crear un nuevo TabSheet.
Pero no sé cómo crearlo con un Memo en su interior como lo he hecho en tiempo de diseño con el primer TabSheet.
Para ser más claro esta es la copia del código con el que ensayo la solución de este problema.
Código:

unit PageControl;

interface

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

type
  TForm1 = class(TForm)
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
    TTabSheet.Create(Self);
    TMemo.Create(Self);
    with TTabSheet.Create(Self) do
    begin
      PageControl := PageControl1;
    end;

end;

end.

Un saludo

roman 27-02-2004 15:53:14

Cita:

Empezado por esocrates
Pero no sé cómo crearlo con un Memo en su interior

[...]

Código:

begin
    TTabSheet.Create(Self);
    TMemo.Create(Self);
    with TTabSheet.Create(Self) do
    begin
      PageControl := PageControl1;
    end;

end;


Debes asignar el TabSheet recién creado a la propiedad Parent del Memo.

// Saludos

esocrates 27-02-2004 17:37:38

Código:

begin
    TTabSheet.Create(Self);
    TMemo.Create(Self);
    with TTabSheet.Create(Self) do
    begin
      PageControl := PageControl1;
    end;

Cita:

Empezado por roman
Debes asignar el TabSheet recién creado a la propiedad Parent del Memo.

// Saludos

Pruebo con tu indicación y no me sale.
¿Cómo sería el código para esta asignación?
Muchas gracias

roman 27-02-2004 18:01:55

¿De qué manera estás intentando la última asignación que te indiqué?

No lo puedes hacer con un simple

Código:

with TTabSheet.Create(Self)
ya que necesitas una referencia al objeto para poder asignarlo. Dicho de otra forma necesitas una variable para almacenar el objeto que te devuelve Create.

// Saludos

esocrates 27-02-2004 18:58:15

Cita:

Empezado por roman
¿De qué manera estás intentando la última asignación que te indiqué?

No lo puedes hacer con un simple

Código:

with TTabSheet.Create(Self)
ya que necesitas una referencia al objeto para poder asignarlo. Dicho de otra forma necesitas una variable para almacenar el objeto que te devuelve Create.

// Saludos

Intento asignarlo de la sgte manera:
Código:

begin
    TTabSheet.Create(Self);
    TMemo.Create(Self);
    with TTabSheet.Create(Self) do
    begin
      PageControl := PageControl1;

    end;
    Memo1.Parent := TabSheet1;
end;

Se crea el TabSheet pero no está el Memo en su interior.
Un saludo y disculpa la insistencia; estoy en los comienzos.

jachguate 27-02-2004 19:01:04

Es que TabSheet1 no apunta a ninguno de los dos tabshets recien creados...

tenes que hacer que el parent sea el tabshet que queres que sea su contenedor...

Hasta luego.

;)

esocrates 27-02-2004 20:57:38

Cita:

Empezado por jachguate
Es que TabSheet1 no apunta a ninguno de los dos tabshets recien creados...

tenes que hacer que el parent sea el tabshet que queres que sea su contenedor...

Hasta luego.

;)

Eso es lo que precisamente no sé hacer. Por eso les pido que lo que me están explicando lo acompañen de algún código de ejemplo; o corrijan el mío.
Me doy cuenta que mi error es de concepto. Eso es lo que más me preocupa.
No tengo urgencia. Lo que quiero es aprender.
Un saludo y gracias por ayudarme.

eduarcol 27-02-2004 21:02:29

Código:

var
  MiHoja: TTabSheet;
begin
  MiHoja :=  TTabSheet.Create(Self)
  MiHoja.PageControl := PageControl1;

  with TMemo.Create(Self) do
      Parent := MiHoja;
end;

Eso es todo

roman 27-02-2004 21:06:05

Cita:

Empezado por esocrates
Me doy cuenta que mi error es de concepto.

Y precisamente por eso no te escribimos el código. No lo tomes a mal, pero si te escribimos el código tal cual entonces no vas a entender el concepto.

Para que el Memo aparezca dentro del TabSheet debes asignarle dicho TabSheet a su propiedad Parent:

Memo.Parent := tab sheet

Lo que tienes que contestarte es: ¿Quién es dicho tab sheet?

Una vez que lo sepas sabrás también qué valor debe tener TabSheet1 antes de asignárselo a Memo1.Parent.

// Saludos

eduarcol 27-02-2004 21:07:43

Upsss, perdon como que eche a perder la clase :rolleyes:

roman 27-02-2004 21:08:14

Bueno, mi respuesta llegó un poco después de la de eduarcol así que será ya tu decisión tratar de entender el concepto y no sólo copiar el código.

// Saludos

esocrates 27-02-2004 21:36:07

Cita:

Empezado por roman
Bueno, mi respuesta llegó un poco después de la de eduarcol así que será ya tu decisión tratar de entender el concepto y no sólo copiar el código.

// Saludos

No sólo que no lo tomo a mal sino que estoy muy agradecido con Uds.
Utilizar código hecho por los que más saben es una menera de empezar en esto, así creo.
Mi intención siempre ha sido entender el concepto. Creo que es el espíritu de este Foro y la gran ayuda que brinda.
Hoy Uds. me han dado mucho para empezar a entender un poco todo esto.
Un saludo y hasta pronto

jachguate 27-02-2004 21:38:30

Está bien. Ahora como ha apuntado roman... es decisión del "alumno" que hacer con la información obtenida.

Has escuchado alguna vez esto:

Cita:

Empezado por Confucio
No le des un pez.. mejor enseñale a pescar?

Si esocrates o cualquier otro ha de permanecer en el mundo de la informática, mejor es que se acostumbre a buscar en la documentación, leer libros, y quemarse las pestañas (yt las neuronas) delante del monitor, intentando y consiguiendo, sobre todo, mejorar sus técnicas de investigación y su habilidad para encontrar información.

La sintaxis... eso es cosa simple. Las ideas, esas si que son complejas....

Hasta luego.

;)

eduarcol 27-02-2004 21:43:09

Cita:

Empezado por jachguate
La sintaxis... eso es cosa simple. Las ideas, esas si que son complejas....


De hecho yo pienso que todos los programadores deberian estar a nivel en conocimientos que los desarrolladores y los diseñadores de sistemas, asi los programas mejorarian su calidad, porq recuerden q:
Cita:

Todo Diseñador de Sistemas puede Programar, Pero no todo Programador puede diseñar Sistemas.
Deberiamos cambiar eso

jachguate 27-02-2004 21:53:03

Cita:

Empezado por eduarcol
Todo Diseñador de Sistemas puede Programar, Pero no todo Programador puede diseñar Sistemas.

Esto equivale a decir que cualquier arquitecto puede construir, pero no cualquier constructor puede diseñar...

Quizas en algunos casos, pero no cualquiera... no me parece que sea correcto.

Hasta luego.

;)

esocrates 28-02-2004 16:12:59

Hola Eduarcol:
Estoy estudiando tu código que me ha sido muy útil:
Código:

var
  MiHoja: TTabSheet;
begin
  MiHoja :=  TTabSheet.Create(Self);
  MiHoja.PageControl := PageControl1;

  with TMemo.Create(Self) do
      Parent := MiHoja;
end;

ESto permite crear tanto un TabSheet como un Memo dentro del mismo.
Ahora Bien: El Memo creado no toma las dimensiones del TabSheet.
La referencia que da Delphi dice que la propiedad Width no funciona para los Controles contenidos en los TabSheet creados en tiempo de ejecución.
Te agradeceré me orientes para conseguir que el Memo creado tome las dimensiones del TabSheet.
Un saludo y hasta pronto

__cadetill 28-02-2004 16:15:53

Dale valor a la propiedad Align a alClient del TMemo

Código:

....
with TMemo.Create(Self) do
  Parent := MiHoja;
  Align := alClient;


eduarcol 28-02-2004 16:19:18

Ubica la propiedad Align del Memo y colocala ALClient
Align := AlClient;

Esta propiedad tiene los valores

Código:

    AlClient :=  Se alinea en toda el area del contenedor
    AlRigth  :=  Se alinea a la derecha del area del contenedor
    AlLeft  :=  Se alinea a la izquierda del area del contenedor
    AlTop  :=  Se alinea en la parte superior del area del contenedor
    AlBottom  :=  Se alinea en la parte inferior del area del contenedor


eduarcol 28-02-2004 16:19:59

Como que respondimos al mismo tiempo :D

esocrates 28-02-2004 20:23:16

Con este intento consigo crear un TabSheet y un Memo. Pero El Memo creado no toma las dimensiones del TabSheet. El Form se maximiza y el TabSheet queda normal con un Memo Mimimizado. He hecho la aplicación varias veces, por si había algún problema y se repite lo mismo.
Si se les ocurre algo para orientarme en cual puede ser el error se los agradeceré.
Un saludo

Código:

  var
  MiHoja: TTabSheet;
begin
  MiHoja :=  TTabSheet.Create(Self);
  MiHoja.PageControl := PageControl1;


  with TMemo.Create(Self) do
      Parent := MiHoja;
      Align := alClient;
end;


__cadetill 28-02-2004 23:08:09

bueno, puedes utilizar los Anchors para anclarla a las posiciones deseadas. Si quieres que se redimensione con el form

Código:

MiHoja.Anchors = [akLeft,akTop,akRight,akBottom];
Creo que sería así :rolleyes:

esocrates 29-02-2004 02:18:51

Hola a todos. He conseguido la solución.
Sé que para Uds. será algo sencillo. Pero para mí que estoy en los comienzos es una gran alegría.
En tiempo de diseño puse align:=alClient al TPageControl para que no quede desproporcionado cuando se maximiza el Form.
Luego con este código creo un panel, un Memo y el correspondiente TabSheet. (ExtCtrls en Uses para el Panel)

Código:

procedure TForm1.Button1Click(Sender: TObject);
var m:integer;

begin
        with TTabSheet.Create(Self) do
                begin
                        PageControl := PageControl1;
                        Name:='Tab'+inttostr(PageIndex);
                        Caption := name;
                        m:=PageIndex;
                        align:=alClient;
                end;
        with TPanel.Create(self) do
                begin
                        parent:= pagecontrol1.Pages[m];
                        name:='Panel'+inttostr(m);
                        caption:=name;
                        align:=alClient;

                end;
        with TMemo.Create(self) do
                begin
                        parent:= pagecontrol1.Pages[m];
                        name:='Memo'+inttostr(m);
                        Align := alClient;
                end;
end;



end.

Muchas gracias por todo lo que me ayudaron
Un saludo y hasta pronto

roman 01-03-2004 00:24:16

Bueno, pero... ¿de dónde sale eso de

Cita:

La referencia que da Delphi dice que la propiedad Width no funciona para los Controles contenidos en los TabSheet creados en tiempo de ejecución.
?

Porque a mi me funciona perfectamente.

// Saludos

eduarcol 01-03-2004 16:03:29

Tomado de la ayuda de delphi
Cita:

Determines how the control aligns within its container (parent control).

property Align: TAlign;

Description

Use Align to align a control to the top, bottom, left, or right of a form or panel and have it remain there even if the size of the form, panel, or component that contains the control changes. When the parent is resized, an aligned control also resizes so that it continues to span the top, bottom, left, or right edge of the parent.

For example, to use a panel component with various controls on it as a tool palette, change the panel’s Align value to alLeft. The value of alLeft for the Align property of the panel guarantees that the tool palette remains on the left side of the form and always equals the client height of the form.

The default value of Align is alNone, which means a control remains where it is positioned on a form or panel.

Tip: If Align is set to alClient, the control fills the entire client area so that it is impossible to select the parent form by clicking on it. In this case, select the parent by selecting the control on the form and pressing Esc, or by using the Object Inspector.

Any number of child components within a single parent can have the same Align value, in which case they stack up along the edge of the parent. The child controls stack up in z-order. To adjust the order in which the controls stack up, drag the controls into their desired positions.

Note: To cause a control to maintain a specified relationship with an edge of its parent, but not necessarily lie along one edge of the parent, use the Anchors property instead.
Pues yo tambien he quedado intrigado, y alli les pego la ayuda de delphi sobre la propiedad align, no dice nada al respecto

Cita:

En tiempo de diseño puse align:=alClient al TPageControl para que no quede desproporcionado cuando se maximiza el Form
Ese si es el problema, Si el padre no se redimensiona no esperes que el hijo lo haga

esocrates 01-03-2004 16:12:51

Cita:

Empezado por roman
Bueno, pero... ¿de dónde sale eso de


?

Porque a mi me funciona perfectamente.

// Saludos

Hola Roman:
A mí no me funcionó y me fui a buscarlo a la ayuda de Delphi 6
para TMemo Properties y encontré esto [Ver la note]
Cita:

Specifies the horizontal size of the control or form in pixels.

property Width: Integer;

Description

Use the Width property to read or change the width of the control.

Note: For tab sheet controls, changing this property at runtime has no effect.
Un saludo

eduarcol 01-03-2004 16:19:03

Perdon lei mal, crei que el que no funcionaba con el TabSheet era el Align, y resulta que es el width :confused:

Pero el align no te funcionaba por lo que te decia anteriormente

roman 01-03-2004 16:30:21

Cita:

Empezado por esocrates
A mí no me funcionó y me fui a buscarlo a la ayuda de Delphi 6
para TMemo Properties y encontré esto [Ver la note]

Pero esto es otra cosa. Originalmente dijiste:

Cita:

Empezado por esocrates
la propiedad Width no funciona para los Controles contenidos en los TabSheet creados en tiempo de ejecución

La referencia a la ayuda que mencionas, para empezar no se refiere a la propiedad Width específicamente de un Memo sino de un Control y no dice que no se pueda cambiar la propiedad Width de un control contenido en un Tab Sheet sino que no se puede cambiar la propiedad Width del TabSheet, lo cual es distinto. De hecho tampoco se puede cambiar durante el diseño ya que funciona similar a cuando se tiene la propiedad Align de cualquier control en alTop, alBottom o alClient: no se puede cambiar su propiedad Width (en diseño o ejecución) porque ésta se ajusta al control contenedor.

// Saludos

esocrates 01-03-2004 21:23:36

Cita:

Empezado por roman
Pero esto es otra cosa. Originalmente dijiste:



La referencia a la ayuda que mencionas, para empezar no se refiere a la propiedad Width específicamente de un Memo sino de un Control y no dice que no se pueda cambiar la propiedad Width de un control contenido en un Tab Sheet sino que no se puede cambiar la propiedad Width del TabSheet, lo cual es distinto. De hecho tampoco se puede cambiar durante el diseño ya que funciona similar a cuando se tiene la propiedad Align de cualquier control en alTop, alBottom o alClient: no se puede cambiar su propiedad Width (en diseño o ejecución) porque ésta se ajusta al control contenedor.

// Saludos

Tenés razón. Muchas gracias
Un saludo

Rowerto 01-12-2010 17:21:21

Hola de nuevo. Aunque no posteo mucho si que entro casi a diario al foro para resolver mis dudas.

En esta ocasion resubo este hilo (bastante antiguo por lo que veo, pero lo prefiero a crear otro nuevo, razones obvias), porque la duda que tengo va en la linea. Tenia en un primer momento la misma duda que tenia esocrates, la de como crear un tabsheet y dentro de este una stringgrid en tiempo de ejecucion y lo dicho, gracias a la ayuda del propio Delphi y de este hilo lo he logrado.
Pero a raiz de esto, tengo otra duda. Y os explico un poco de como va el programa en el que estoy currando ahora para que me podais ayudar mejor.

Yo abro un/os fichero/s y recojo en un primer momento ciertos datos que necesito.
Esta info es el nombre de un sitio, su matricula y el dia de "autos" (como en cualquier producto: tipo, referencia y dia).
Si este sitio no tiene pestaña propia, debo crear una (en tiempo de ejecucion) con su propio stringgrid asociado, y de existir debo pasar la hoja de ese sitio y por ende su stringgrid. Una vez hecho esto relleno la grid con los datos del fichero abierto.
Yo consigo hacerlo todo salvo pasar el stringgrid asociado a la hoja con el sitio.
Os paso algo de codigo para que se entienda "mejor":

Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var   tabs : ttabsheet;
      stri : tstringgrid;   //hay mas variables, pero pongo solo las que creo que os seran necesarias saber el tipo para entenderlo
begin
  memo1.Lines.Clear;  //en este memo (se que se puede hacer con otras cosas) meto los nombres de los ficheros que abro desde el dialogo
          //de apertura
  opendialog1.Execute;
  memo1.Lines :=opendialog1.Files;
  for y:=0 to memo1.Lines.Count-1 do  //recorro el memo para abrir todos los ficheros seleccionados antes
  begin
    memo2.Lines.LoadFromFile(memo1.Lines[y]);//copio el contenido de cada fichero independiente

    {recojo la informacion que necesito para ver si ya existe, aunque tampoco lo pongo
     matricula y centro que son unas strings}

    compara:=0;
    for z:=0 to pagecontrol1.PageCount-1 do    //miro pagina por pagina el caption y de ser igual paso en compara el numero
    begin
      if comparestr(trim(PageControl1.Pages[z].Caption), trim(trim(centro)+trim(matricula)))=0
      then begin
        compara:=z+1;    //pasa el numero de pagina (o 0 en su defecto si llega al final y no encuentra ninguno)
      end;
    end;       //posiblemente este bucle se pueda juntar con el proximo IF, cosa a revisar cuando todo funcione

    if compara - 1  = 0   //si no encuentra un caption igual creo tanto la tab como la grid (y sus dimensiones)
    then begin
      tabs := TTabSheet.Create(PageControl1);
      tabs.PageControl := PageControl1;
      tabs.Name := 'TabSheet'+inttostr(pagecontrol1.PageCount+1);
      memo3.Lines.Add(tabs.name);
      tabs.Caption := trim(centro)+trim(matricula);
      stri := tstringgrid.Create(self);
      stri.Parent := tabs;
      stri.Name := 'StringGrid'+inttostr(pagecontrol1.PageCount+1);
      stri.Visible:=true;
      stri.ColCount:=8;
      stri.FixedCols:=0;
      stri.RowCount:=3;
      stri.FixedRows:=2;
      stri.Width:=529;
      stri.Height:=601;
      stringcabecera(stri);
    end
    else begin     // y si lo encuentra le paso la pagina y la grid
      tabs := PageControl1.Pages[z];
      stri := ///////////AQUI LO QUE ME FALTA que es el grid que hay en ese pagecontrol1.pages[z]
    end;

    {aqui viene todo el troncho de rellenado de datos que elimino para que se entienda mejor el resto}

  pagecontrol1.ActivePage:=tabs; //activo la pagina (sea nueva o no)

  end;
end;

Espero que me podais ayudar, porque no se ni por donde empezar.
Perdon por el tronchazo que os acabo de soltar y gracias de antemano!!

jachguate 05-12-2010 00:45:00

No estoy seguro de entender bien lo que querés... es asignar a la variable stri el StringGrid que ya está contenido en el TabSheet??

Saludos.

Rowerto 09-12-2010 12:11:06

Pues si, exactamente eso.

jachguate 10-12-2010 23:38:26

Si el string grid tiene un nombre, tan fácil como:

Código Delphi [-]
  tabs := PageControl1.Pages[z];
  stri := Tabs.FindControl('ElNombreDelStrignGrid') as TStringGrid;

Si no lo tiene... pero hay solo uno, entonces algo como esto:

Código Delphi [-]
  tabs := PageControl1.Pages[z];
  stri := nil;
  for I := 0 to Tabs.ControlCount - 1 do
    if Tabs.Controls[i] is TStringGrid then
    begin
      stri := TStringGrid(Tabs.Controls[i]);
      break;
    end;

Esto funcionará si el StringGrid está directamente sobre el PageControl. Si está en otro control, pues se busca directamente en ese contenedor... o se hace una búsqueda recursiva.

Si hay varios StringGrid, pues sería de idear la forma de identificar cuál es el que te interesa y condicionar la asignación hasta que se encuentre el indicado.

Un saludo.

Rowerto 13-12-2010 17:07:19

Muchisimas gracias jachguate, ha sido una aclaracion diafana y cristalina.
Como cada tabsheet solo tiene un control (que es la stringgrid) lo unico que pongo es:

Código Delphi [-]
stri := Tstringgrid(pagecontrol1.Pages[z].Controls[0]);

y va todo como un tiro.

La verdad, que se me cayo la cara de vergüenza al ver lo simple y facil que era. Yo me estaba rompiendo los cuernos con Controls, Parents y este tipo de cosas... por lo que solo puedo repetir : GRACIAS POR LA AYUDA!!!! ;)


La franja horaria es GMT +2. Ahora son las 21:45:35.

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