TTabsheet at runtime generieren

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
malabarista
Beiträge: 321
Registriert: Sa 11. Jun 2016, 12:16
OS, Lazarus, FPC: Linux Mint 18.1 L1.6.2-1 FPC 3.0.0
CPU-Target: 64Bit
Wohnort: Konstanz

TTabsheet at runtime generieren

Beitrag von malabarista »

Ich habe ein eigenartiges Problem beim Erzeugen von TTabsheets at runtime.
Mein Beispiel macht Folgendes:
Per Buttonclick kann ich in einem TPageControl neue TTabsheets anlegen. Jedes TTabsheet erhält ein eigenes Formular:
tab0 hat Form0, tab1 hat Form1, ...
Nachdem ich tab0 und tab1 erzeugt und angezeigt habe und dann auf tab0 klicke, wird mir aber Form1 statt Form0 angezeigt.
Um die Forms zu unterscheiden hat jedes seine eigene Nummer in der Anzeige.

Code: Alles auswählen

 
unit testtabu;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls,
  StdCtrls,tabinu;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    act: TLabel;
    pcon: TPageControl;
    procedure change0(Sender: TObject);
    procedure create0(Sender: TObject);
    procedure neu_tab(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
var dbanz:integer;
 
var dbfeld:array[0..50] of TFtabin;
 
{ TForm1 }
 
procedure TForm1.create0(Sender: TObject);
begin
  dbanz:=0;
  width:=800;
  height:=600;
end;
 
procedure TForm1.change0(Sender: TObject);
begin
act.caption:='aktiv wechsel zu tab'+inttostr(pcon.ActivePageIndex);
dbfeld[pcon.ActivePageIndex].aufruf;
end;
 
procedure TForm1.neu_tab(Sender: TObject);
 
var
   i:integer;
   newtab:ttabsheet;
   z, zz:string;
 
begin
  newtab:=ttabsheet.create(pcon);
  newtab.PageControl:=pcon;
  newtab.Name:='tab'+inttostr(dbanz);
  newtab.Caption:=newtab.Name;
  dbfeld[dbanz]:= TFtabin.Create(newtab);
  dbfeld[dbanz].parent:=newtab;
  z:='tabin'+inttostr(dbanz);
  dbfeld[dbanz].start(z,dbanz);
  pcon.ActivePageIndex:=dbanz;
  dbanz:=dbanz+1;
end;
 
end.
 
 

Code: Alles auswählen

 
unit tabinu;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
 
type
 
  { TFtabin }
 
  TFtabin = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    znr: TLabel;
    zz: TLabel;
    procedure create0(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
    procedure start(t:String; tnr:integer);
    procedure aufruf;
  end;
 
var
  Ftabin: TFtabin;
 
implementation
 
{$R *.lfm}
 
{ TFtabin }
 
var
  aktnr:integer;
  aktz:String;
 
procedure TFtabin.create0(Sender: TObject);
begin
  width:=700;
  height:=500;
  aktnr:=0;
  aktz:='';
end;
 
procedure TFtabin.aufruf;
begin
  znr.caption:=inttostr(aktnr);
  zz.caption:=aktz;
end;
 
procedure TFtabin.start(t:String; tnr:integer);
begin
  width:=750;
  height:=500;
  aktnr:=tnr;
  aktz:=t;
  znr.caption:=inttostr(aktnr);
  zz.caption:=aktz;
  show;
end;
 
end.
 

Ich habe das Testprojekt als zip beigefügt.

Was ist mein gedanklicher Fehler ?
Dateianhänge
testtab.zip
(125.65 KiB) 44-mal heruntergeladen

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: TTabsheet at runtime generieren

Beitrag von Michl »

malabarista hat geschrieben:Nachdem ich tab0 und tab1 erzeugt und angezeigt habe und dann auf tab0 klicke, wird mir aber Form1 statt Form0 angezeigt.
Um die Forms zu unterscheiden hat jedes seine eigene Nummer in der Anzeige.
Klammere mal folgende Zeilen aus:

Code: Alles auswählen

procedure TFtabin.aufruf;
begin
//  znr.caption:=inttostr(aktnr);
//  zz.caption:=aktz;
end;
dann siehst du, daß alles gut ist (mit jedem neuen erstelltem TFtabin werden die globalen Varialen aktnr und aktz überschrieben und in o.g. Methode überschreibst du jeweils die Captions).

PS: Der Code ist sehr schwer zu lesen, bessere Bezeichner sind oft vorteilhaft. Man braucht sie während des Codens auch nicht immer voll einzutippen, die Anfangsbuchstaben + <Strg> + <Leerzeichen> sind da sehr nützlich.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

malabarista
Beiträge: 321
Registriert: Sa 11. Jun 2016, 12:16
OS, Lazarus, FPC: Linux Mint 18.1 L1.6.2-1 FPC 3.0.0
CPU-Target: 64Bit
Wohnort: Konstanz

Re: TTabsheet at runtime generieren

Beitrag von malabarista »

Danke. Du hast meinen Fehler gefunden.
Wieso sind die global ?
Wo (=in welchem Abschnitt) muss ich die denn definieren, damit sie in jedem Formular lokal sind ?

malabarista
Beiträge: 321
Registriert: Sa 11. Jun 2016, 12:16
OS, Lazarus, FPC: Linux Mint 18.1 L1.6.2-1 FPC 3.0.0
CPU-Target: 64Bit
Wohnort: Konstanz

Re: TTabsheet at runtime generieren

Beitrag von malabarista »

Vielleicht habe ich meine Absicht zu kompliziert dargestellt.
Also noch ein besseres Beispiel.
Jedes Formular soll einen Kreis zeichnen.
Form0 mit dem Radius 5, Form1 mit dem Radius 7, ...
Diese Variable Radius: wo (=in welchem Abschnitt) muss ich die definieren, damit jedes Form auf seinen richtigen Radius zugreift ?

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: TTabsheet at runtime generieren

Beitrag von Michl »

malabarista hat geschrieben:Wo (=in welchem Abschnitt) muss ich die denn definieren, damit sie in jedem Formular lokal sind ?
https://www.delphi-treff.de/object-pascal/allgemeines-ueber-variablen-und-konstanten/

z.B.:

Code: Alles auswählen

unit tabinu;
...
type
  TFtabin = class(TForm)
...
  private
    aktnr:integer;
    aktz:String;
...
  end;
 
implementation
 
//var
//  aktnr:integer;
//  aktz:String;
 

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

malabarista
Beiträge: 321
Registriert: Sa 11. Jun 2016, 12:16
OS, Lazarus, FPC: Linux Mint 18.1 L1.6.2-1 FPC 3.0.0
CPU-Target: 64Bit
Wohnort: Konstanz

Re: TTabsheet at runtime generieren

Beitrag von malabarista »

Danke.
Jetzt habe ich es verstanden wo solche "lokalen" Variablen hin müssen.

Antworten