Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - 50 Buttons


willi - So 06.10.02 15:45
Titel: 50 Buttons
hi,
ich habe ein Programm das an die 50 Buttons enthält, auf die ich einzeln anklicken möchte. Nun will ich aber nicht für jeden einzelnen Button eine eigene Prozedur mit einem OnClick-Ereignis schreiben, sondern einfach eine Prozedur haben, in der ich dann weiß, auf welchen Button geklickt wurde.
Habe mir schon überlegt, es mir der Mausposition auszurechnen, aber das fand ich auch nicht so toll.
Ach ja, wenn ich auf einen Button klick, dann soll nur die Caption der Form geändert werden, sonst nichts...
Hat jemand eine Idee???

Danke
Willi


bis11 - So 06.10.02 16:12

Hi,

du machst ein OnClick-Ereignis, was Du in jeden Button einfügst im Obejktinspektor. Das Ereignis könnte so aussehen :


Quelltext
1:
2:
3:
4:
5:
6:
procedure TForm1.Button1Click(Sender: TObject);
begin
  if Button1.Focused then Form1.Caption := Button1.Caption;
  if Button2.Focused then Form1.Caption := Button2.Caption;
  if Button3.Focused then Form1.Caption := Button3.Caption;
end;


Christian S. - So 06.10.02 16:27

Kann man das nicht so machen?


Quelltext
1:
Form1.Caption:=TButton(Sender).Caption;                    


MfG,
Peter


bis11 - So 06.10.02 16:42

Hallo Peter,

du hast recht, warum einfach wenn's auch umständlich geht. Bin halt nicht gleich draufgekommen :mrgreen:


willi - So 06.10.02 17:05

Nein, sorry, so klappt des net. Denn die Caption soll sich ja nur ändern, wenn ein Button angeklickt wird und das erfahr ich ja dadurch nicht.

Ich habe die Buttons auch schon in ein Array of Buttons geladen. Was auch wunderbar klappt. Habe nun immer, wenn sich der Focus ändert, abgefragt, ob ein Button den Focus hat. Das hat aber irgendwie nicht ganz richtig funktioniert, da die Buttons sich nur einmal anklicken lassen, danach is schluss :?
Am Besten wär es wenn ich ein OnClick-Ereignis von dem Array abrufen könnt. Also zum Beispiel (Array[].OnClick, dies klappt natürlich nicht). Da habe ich aber auch keine Ahnung, wie des gehen soll...

MFG
Willi


bis11 - So 06.10.02 17:10

Hi,

definiere mal, was sich ändern soll ? Die Caption der Form oder die Caption der Buttons oder was ? Denn die beiden Code-Beispiele funktionieren. Denn Du schreibst es etwas undurchsichtlich.


Christian S. - So 06.10.02 17:23

Hi!

Wenn Du meinen Quelltext jedem Button als OnClick-Ereignis zuweist, dann wird, wenn auf einen Button geklickt wird, die Form den Titel erhalten, den der Button hat. Der Quelltext von bis11 tut das Gleiche!

MfG,
Peter


willi - So 06.10.02 17:33

Ok, ich wollte es etwas kürzen, aber was solls...

ich habe 50 Buttons und wenn ich auf einen klicke, dann soll sich ein neues Fenster öffnen (Form2). Und die Caption der Form2 soll den Text des Buttons einnehmen ( Also: Form2.caption:=button?.caption).

Nun kann ich es so lösen, indem ich für jeden Button eine eigene Procedur schreibe:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure button1.onclick;
begin
 form2.show;
 Form2.caption:=button1.caption;
end;

procedure button2.onclick;
begin
 form2.show;
 Form2.caption:=button2.caption;
end;


Das wäre aber für 50 Button etwas mühsam und bescheuert.
Deswegen habe ich die ganzen Buttons in ein Array reingeschrieben mit:


Quelltext
1:
for i:=1 to 50 do Tage[i]:=TButton(FindComponent('Button'+IntToStr(i)));                    


Dies klappt auch.
Aber jetzt weiß ich nicht, wie ich ein OnClick-Ereignis aufrufen kann, wie zum Beispiel

Quelltext
1:
procedure tage[].OnClick;                    

Das klappt natürlich NICHT...
Aber das mit Form1.Caption:=TButton(Sender).Caption; ist eine sehr gute Idee. Danke
Gibt es vielleicht sowas wie TButton(Sender).OnClick????


So, ist es vielleicht jetzt etwas verständlicher???
Ich hoffe doch
Vielen Dank
Willi


bis11 - So 06.10.02 17:40

Dann machste das halt so :


Quelltext
1:
2:
3:
4:
5:
procedure TForm1.Button1Click(Sender: TObject); 
begin 
  Form2.Show;
  Form2.Caption:=TButton(Sender).Caption;
end;


Dann diese Procedure in jedes OnClick-Ereignis von jedem Button setzen.


willi - So 06.10.02 17:51

Das ist es doch grad... ich will nicht 50 OnClick-Eriegnis Proceduren schreiben, sondern nur eine einzige Procedur. Ist das möglich :?:


Christian S. - So 06.10.02 17:59

geht das nicht so:


Quelltext
1:
2:
3:
4:
5:
procedure TForm1.alles_klick(Sender: TObject); 
begin 
  Form2.Show; 
  Form2.Caption:=TButton(Sender).Caption; 
end;


dann so: (Deine Schleife, nur geändert)


Quelltext
1:
2:
3:
4:
5:
for i:=1 to 50 do
begin
  Tage[i]:=TButton(FindComponent('Button'+IntToStr(i)));
  TButton(FindComponent('Button'+IntToStr(i))).OnClick:=alles_klick;
end;


MfG,
Peter

P.S.: Quelltext nicht getestet!


bis11 - So 06.10.02 18:02

Willi,

Zitat:
Dann diese Procedure in jedes OnClick-Ereignis von jedem Button setzen.


Das habe ich im letzten Posting geschrieben, Du kannst eine Procedure mehren Buttons zuweisen, dies alles machst Du im Objektinspektor.


Christian S. - So 06.10.02 18:16

bis11 hat folgendes geschrieben:

Du kannst eine Procedure mehren Buttons zuweisen, dies alles machst Du im Objektinspektor.

Stimmt, das geht auch. Trotzdem würde es mich interessieren, ob meine Methode auch funktioniert.

MfG,
Peter


Delete - So 06.10.02 18:22

Wie wäre es damit:

Quelltext
1:
2:
3:
4:
case TButton(Sender).Tag of
  1: ....;
  2: ....;
end;


Christian S. - So 06.10.02 18:25

@Luckie:
Ist das für das gegebene Problem nicht etwas umständlich? Er will doch nur Caption vom Button für die Form2 übernehmen ... Hoffe ich.

MfG,
Peter


willi - So 06.10.02 18:44

Ja genau, richtig erkannt. Es ist etwas umständlich.

@ bis11: ok, das würde gehen und nicht soo umständlich. Aber was wäre wenn man 1000 Buttons hat?? :D Ok, es ist übertrieben, aber mich interessiert es auch, ob es anders geht

@Peter Lustig: Ich hab es ausprobiert, aber geklappt hat es leider nicht :(
Bei mir bringt er den Fehler:
Inkompatible Typen: Liste der Parameter ist unterschiedlich.
Vielleicht hab auch ich was falsch gemacht.

MFG


Delete - So 06.10.02 18:47

War nur ein Vorschlag, eventuell wird es an anderer Stelle noch gebraucht.


Christian S. - So 06.10.02 18:51

Hi!

Habe es gerade mal ausprobiert (den Teil mit dem Array nicht, sondern den Teil der Schleife, den ich hinzugefügt habe). Bei mir funktioniert das. Ist zwar etwas lang, aber so sieht das bei mir aus:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure FormCreate(Sender: TObject);
    procedure alles_klick(Sender:Tobject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.alles_klick(Sender:Tobject);
begin
  form1.Caption:=TButton(sender).caption;
end;

procedure TForm1.FormCreate(Sender: TObject);
VAR i : INTEGER;
begin
  for i:=1 TO 3 DO
  TButton(FindComponent('Button'+IntToStr(i))).OnClick:=alles_klick;
end;


MfG,
Peter


bis11 - So 06.10.02 18:53

Das ist wohl schon ein bißchen Übertrieben und ich glaube das man das auch nicht brauchen wird. Aber natürlich geht das auch für 1000 Buttons.


willi - So 06.10.02 19:04

Ja, danke Peter Lustig. Es klappt wunderbar. Ich habe vorhin nur einen ganz dummen Fehler reingemacht :oops:
Aber nach deiner Methode klappt es wunderbar und ist am unaufwendigsten.

@bis11:klar kann man das auch für 1000 Buttons machen, nur mit welchen Aufwand??
Auch dir danke, wäre das nächste, was ich gemacht hätte...

Trotzdem danke an alle. Hätte nicht gedacht, dass ich so schnell Antworten bekomm

DANKE
willi


Wolff68 - So 06.10.02 20:18

Um nochmal auf das Array of Buttons zurückzukommen.
Das geht natürlich auch. Nur musst Du dann natürlich diese auch selber erzeugen und positionieren usw.

Also sowas:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
hButton : Array[1..50] of TSpeedButton; // Gobal angelegt

In Form.Create dann:
For i := 1 to 50 do begin
  hButton[i] := TSpeedButton.Create(Self);
  With hButton[i] do begin
    Parent := <zB Form1 oder GroupBox>
    Height := ....
    Width := ....
    OnClick := <ClickProzedur>;
    ..... usw.
  end;
end;

Danach kannst dann einfach mit hButton[<nummer>] auf jeden Button zugreifen.

Nur der Vollständigkeit halber. Für Deinen Einsatz ist das von Peter sicher weniger aufwändig.