Komponenten abfragen

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Justuv
Beiträge: 13
Registriert: So 1. Dez 2013, 11:41

Komponenten abfragen

Beitrag von Justuv »

Gegeben: Mehrere Panel (über 200) auf einer Form. Gibt es eine Möglichkeit zu ermitteln welches angeklickt wurde? Natürlich kann ich per OnClick oder OnMouseEnter darauf reagieren, aber dann habe ich auch genau so viel Proceduren in welchen ich dann lediglich das jeweilige Panel erkenne. Geht das eleganter?

Grüße Jürgen

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6770
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Komponenten abfragen

Beitrag von af0815 »

Justuv hat geschrieben: Mo 13. Feb 2023, 11:47 Gegeben: Mehrere Panel (über 200) auf einer Form. Gibt es eine Möglichkeit zu ermitteln welches angeklickt wurde? Natürlich kann ich per OnClick oder OnMouseEnter darauf reagieren, aber dann habe ich auch genau so viel Proceduren in welchen ich dann lediglich das jeweilige Panel erkenne. Geht das eleganter?
Ja, alle Panels haben dieselbes OnClick, auseinanderhalten kann man die dann, wenn man den Sender abfrage, welches Panel es ausgelöst. Auch den Tag kann man verwenden um dort eine Zahl hinterlassen, mit dem man das auseinanderhalten kann.

Zuerst den sender abfragen ob er vom richtigen Typ ist, wenn ja, dann kann man den casten und dann entweder das Tag oder den Namen abfragen.

Ich mache in einem solchen Fall (wenn es möglich ist) entweder ein StringGrid, indem ich dann Buttons einblende oder die Panels werden zur Laufzeit erzeugt.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
six1
Beiträge: 837
Registriert: Do 1. Jul 2010, 19:01

Re: Komponenten abfragen

Beitrag von six1 »

Code: Alles auswählen

procedure TForm1.Panel1Click(Sender: TObject);
var
  MyName:String:
begin
  MyName:=(Sender as TPanel).Name;
end;
Gruß, Michael

Frank Ranis
Beiträge: 210
Registriert: Do 24. Jan 2013, 21:22

Re: Komponenten abfragen

Beitrag von Frank Ranis »

Hallo Jürgen ,

hier hast Du was zum spielen und grübeln.

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private

  public
    procedure panel_klick_routine(sender:tobject);
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

// Panels erzeugen und auf dem Schirm platzieren
procedure TForm1.FormCreate(Sender: TObject);
var x,y,panel_nr:integer;
    panel:tpanel;
const rand=10;
      pan_Width=45; // Breite eines Panels
      pan_Heigth=25; // Höhe eines Panels
      anz_x=20; // Anzahl der Panels in X-Richtung
      anz_y=10; // Anzahl der Panels in Y-Richtung
begin
 form1.Position:=poScreenCenter;
 // Form Breite und Höhe einstellen
 form1.Width:=anz_x*pan_Width+(anz_x+1)*rand;
 form1.Height:=anz_y*pan_Heigth+(anz_y+1)*rand;

 panel_nr:=1; // Nummerierung der Panels , Startwert 1
 // Panels erzeugen
 for y:=0 to anz_y-1 do
  for x:=0 to anz_x-1 do
   begin
    // neues Panel erzeugen und Form 1 als Owner und Parent zuweisen
    panel:=tpanel.Create(form1);
    panel.Name:='Pan_'+Inttostr(panel_nr); // Name zuweisen , damit man es später auch findet
    panel.Parent:=form1;
    // Höhe und Breite der Panels
    panel.Width:=pan_Width;
    panel.Height:=pan_Heigth;
    // Text auf dem Panel
    Panel.Caption:=panel.name;
    // Position der Panels
    panel.Left:=x*(pan_Width+rand)+rand;
    panel.top:=y*(pan_Heigth+rand)+rand;

    // Die Click-Routine zuweisen , ist immer die gleiche
    panel.OnClick:=@panel_klick_routine;

    inc(panel_nr) // Panel_nr hochzählen
   end;
end;

// Eine Klickroutine für alle Panels gleich
procedure TForm1.panel_klick_routine(sender: tobject);
var i:integer;
    comp:tcomponent;
begin
 // Checken , ob der Sender von Type Tpanel ist
 if sender is tpanel
  then
   begin
    // Info im Programmkopf ausgeben
    form1.caption:=tpanel(sender).Name+' wurde geklickt!';

    // alle Tpanels mit Defaultfarbe einstellen
    for i:=0 to form1.ComponentCount-1 do
     begin
      comp:=form1.Components[i];
      if tcomponent(comp) is tpanel
       then tpanel(comp).Color:=cldefault;
     end;

    // Nur das aktuelle aktive Panel in Farbe rot
    tpanel(sender).Color:=clred;
   end;
end;

end.                
Gruß

Frank
www.flz-vortex.de

wp_xyz
Beiträge: 5142
Registriert: Fr 8. Apr 2011, 09:01

Re: Komponenten abfragen

Beitrag von wp_xyz »

Frank Ranis hat geschrieben: Mo 13. Feb 2023, 13:30

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
...
 form1.Position:=poScreenCenter;
Sorry, wenn ich jetzt wieder oberlehrerhaft anmerke, dass das schlechter Code ist: Verwende nie den Namen der Instanz im Code einer Klasse. Wenn dein Formular einmal mit dem Namen "MultiPanel_Form" erzeugt wird, funktioniert dein Code nicht mehr, denn er setzt voraus, dass das Formular den Namen "Form1" hat. Lasse einfach "Form1" weg, die Formularklasse weiß schon, welche Controls dazugehören. Und wenn du einmal den Namen der Formularinstanz benötigst (z.B. in panel := TPanel.Create(...)), dann nehme den Bezeichner "self" statt "Form1" - "self" wird immer durch den aktuellen Variablennamen ersetzt.

Code: Alles auswählen

// Panels erzeugen und auf dem Schirm platzieren
procedure TForm1.FormCreate(Sender: TObject);
var x,y,panel_nr:integer;
    panel:tpanel;
const rand=10;
      pan_Width=45; // Breite eines Panels
      pan_Heigth=25; // Höhe eines Panels
      anz_x=20; // Anzahl der Panels in X-Richtung
      anz_y=10; // Anzahl der Panels in Y-Richtung
begin
 Position:=poScreenCenter;
 // Form Breite und Höhe einstellen
 Width:=anz_x*pan_Width+(anz_x+1)*rand;
 Height:=anz_y*pan_Heigth+(anz_y+1)*rand;

 panel_nr:=1; // Nummerierung der Panels , Startwert 1
 // Panels erzeugen
 for y:=0 to anz_y-1 do
  for x:=0 to anz_x-1 do
   begin
    // neues Panel erzeugen und Form 1 als Owner und Parent zuweisen
    panel:=tpanel.Create(Self);  // Self statt "form1"
    panel.Name:='Pan_'+Inttostr(panel_nr); // Name zuweisen , damit man es später auch findet
    panel.Parent:=Self;
    // Höhe und Breite der Panels
    panel.Width:=pan_Width;
    panel.Height:=pan_Heigth;
    // Text auf dem Panel
    Panel.Caption:=panel.name;
    // Position der Panels
    panel.Left:=x*(pan_Width+rand)+rand;
    panel.top:=y*(pan_Heigth+rand)+rand;

    // Die Click-Routine zuweisen , ist immer die gleiche
    panel.OnClick:=@panel_klick_routine;

    inc(panel_nr) // Panel_nr hochzählen
   end;
end;

// Eine Klickroutine für alle Panels gleich
procedure TForm1.panel_klick_routine(sender: tobject);
var i:integer;
    comp:tcomponent;
begin
 // Checken , ob der Sender von Type Tpanel ist
 if sender is tpanel
  then
   begin
    // Info im Programmkopf ausgeben
    caption:=tpanel(sender).Name+' wurde geklickt!';

    // alle Tpanels mit Defaultfarbe einstellen
    for i:=0 to ComponentCount-1 do
     begin
      comp:=Components[i];
      if tcomponent(comp) is tpanel
       then tpanel(comp).Color:=cldefault;
     end;

    // Nur das aktuelle aktive Panel in Farbe rot
    tpanel(sender).Color:=clred;
   end;
end;

Frank Ranis
Beiträge: 210
Registriert: Do 24. Jan 2013, 21:22

Re: Komponenten abfragen

Beitrag von Frank Ranis »

Hallo wp_xyz ,

danke für den Klaps .

Gruß

Frank
www.flz-vortex.de

Benutzeravatar
theo
Beiträge: 10869
Registriert: Mo 11. Sep 2006, 19:01

Re: Komponenten abfragen

Beitrag von theo »

Justuv hat geschrieben: Mo 13. Feb 2023, 11:47 Gegeben: Mehrere Panel (über 200) auf einer Form.
Und das noch: Wer mehr als 10 Panels auf einem Formular hat, hat mMn einen falschen Lösungsansatz gewählt. :wink:

Mathias
Beiträge: 6910
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Komponenten abfragen

Beitrag von Mathias »

Auch den Tag kann man verwenden um dort eine Zahl hinterlassen, mit dem man das auseinanderhalten kann.
Der ".name" kann man auch verwenden, bei Tag ist man auf Zahlen beschränkt.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten