Autor Beitrag
Gahero
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 193

Win Vista HP 64bit
Delphi 2007 Pro
BeitragVerfasst: Di 12.09.06 17:22 
Hi, ich brauch mal eure Hilfe. Ich habe mal wieder ein Problem mit Checkboxen.

Ich möchte, dass er, wenn man eine Checkbox anklickt, diese checked:=true setzt und zu einer Variable einen bestimmten Wert dazuzählt. Das Problem ist, dass es sehr viele Checkboxen sind und ich keine Lust habe, für jede Checkbox eine eigene if-Abfrage zu schreiben. Hat jmd einen besseren Vorschlag?
ConditionZero
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 190

Win XP
Delphi 7 PE, C++ (Dev-C++), HTML+PHP (Dreamweaver MX), JavaScript(MS FrontPage)
BeitragVerfasst: Di 12.09.06 17:33 
Ja, du könntest eine Schleife durchlaufen lassen, wieviele sind es denn ungefähr?
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 12.09.06 17:38 
Ist das immer die gleiche Variable, oder brauchst Du soviele variablen wie Checkboxen auch?

ggf. ist aber FindComponent und der Parameter Sender für dich schon ideal ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
alias5000
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2145

WinXP Prof SP2, Ubuntu 9.04
C/C++(Code::Blocks, VS.NET),A51(Keil),Object Pascal(D2005PE, Turbo Delphi Explorer) C# (VS 2008 Express)
BeitragVerfasst: Di 12.09.06 17:40 
*einwerf* ...Und eigentlich haben Checkboxen ja das natürliche Verhalten, dass sie sich auf checked=true setzen, wenn man sie anklickt...

_________________
Programmers never die, they just GOSUB without RETURN
ConditionZero
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 190

Win XP
Delphi 7 PE, C++ (Dev-C++), HTML+PHP (Dreamweaver MX), JavaScript(MS FrontPage)
BeitragVerfasst: Di 12.09.06 17:45 
Ja ich denk aba mal das er es so meint:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
var
i:Integer;
begin
if CheckBox1.Checked=true then
  begin
  i:=i+1;
  end;
end;


d.h. es bringt ja eig. nichts zur Sache das ein klick checked auf true setzt, oder versteh ich da jetzt was falsch? Wenn man für jeweils eine variable pro checkbox hat, würde ich sagen, man schreibt die abfragen einzeln.

Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt
Gahero Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 193

Win Vista HP 64bit
Delphi 2007 Pro
BeitragVerfasst: Mi 13.09.06 21:29 
Hi,

es gibt dabei aber ein paar Probleme:

1.) Es sind sehr viele Checkboxen (ich glaub über 50) und es sind ungefähr 6 Variablen.

2.) Ich bin Anfänger in Delphi, also wäre ich euch sehr dankbar,wenn ihr dass so erklärt, dass ich dass verstehe. (Das von Condition Zero versteh ich)

Zur Erklärung:
Wenn man eine Checkbox anklickt soll er das Häckchen machen und pro Checkbox zu EINER Variable pro Checkbox etwas hinzurechen.
ConditionZero
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 190

Win XP
Delphi 7 PE, C++ (Dev-C++), HTML+PHP (Dreamweaver MX), JavaScript(MS FrontPage)
BeitragVerfasst: Mi 13.09.06 21:37 
ok, weißt du wie man eine Schleife macht? Und welche man dafür benötigt? (wenn man alles vorschwafelt ist ja der Lerneffekt=0) <<< IGNORIEREN! Sorry da hab ich mich jetzt vertan habe falschherum gedacht ;) also ne schleife wäre da meines wissens nach nicht möglich bzw. man müsste genauso für jede checkbox ne schleife schreiben un hätte mindestens genausoviel arbeit... also ehrlich gesagt würde ich da gar nich lange rummachen und nachgeben (der klügere gibt nach :D) aber du kannst trozdem eine einzige abfrage machen die is aba halt dementsprechend lang hast aba trozdem en bissl arbeit gespart des wär mit OR also so würd die abfrage dann aussehen

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
var
i:Integer;
begin
i:=0;
if CheckBox1.Checked=true OR (Checkbox2.Checked=true) then //Also eig. nur des^^
  begin
  i:=i+1;
  Label1.Caption:= IntToStr(i);
  end;
end;


Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt
Gahero Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 193

Win Vista HP 64bit
Delphi 2007 Pro
BeitragVerfasst: Do 14.09.06 17:57 
Ja, aber es soll ja nicht immer derselbe Wert sein, der dazu addiert wird.
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Do 14.09.06 18:48 
Da gibt es natürlich viele Möglichkeiten, hier ist eine davon:
Alle Komponenten haben eine Eigenschaft 'Tag' (engl: "Schildchen" oder "Etikett"). Das wird nirgendswo benötigt und ist eigentlich nur für solche Probleme wie Deine gedacht:
Wir haben also 6 Variablen, nennen wir die einfach A,B,C,D,E,F und G. Das geht auch mit einem Array, aber dazu im 2.Schritt.

Zunächst definierst Du, welche Checkboxen denn nun welchen Wert hochzählen sollen. Alle Checkboxen, die A hochzählen, verpasst Du die Tag-Eigenschaft '1'. Alle, die B hochzählen '2' usw.

Dann brauchst Du nur noch ein OnClick-Event:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
Procedure TMyForm.CheckBoxClick (Sender : TObject);
Begin
  Case TCheckBox (Sender).Tag of
    1 : A := A + 1;
    2 : B := B + 1;
    3 : C := C + 1;
    4 : D := D + 1;
    5 : E := E + 1;
    6 : F := F + 1;
  End;
End;

Fertig.
Wenn Du lieber mit Arrays arbeitest, dann wirds noch kürzer: Sei MyArray[1] = A usw.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
Procedure TMyForm.CheckBoxClick (Sender : TObject);
Var
  i  : Integer;
Begin
  i := TCheckBox (Sender).Tag;
  MyArray[i] := MyArray[i] + 1;
End;


So, jetzt willst Du vielleicht immer unterschiedliche Werte dazuaddieren? Dann kodiere das auch in die Tag Eigenschaft. Zum Beispiel so:
ausblenden Delphi-Quelltext
1:
CheckBox.Tag := 10000 * VariablenIndex + Zähler;					

Das Ereignis wird nur ein bisserl komplexer;
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
Procedure TMyForm.CheckBoxClick (Sender : TObject);
Var
  i,d  : Integer;
Begin
  i := TCheckBox (Sender).Tag;
  d := i mod 10000;
  i := i div 10000;
  MyArray[i] := MyArray[i] + d;
End;

Eigentlich simpel, oder?

_________________
Na denn, dann. Bis dann, denn.
Gahero Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 193

Win Vista HP 64bit
Delphi 2007 Pro
BeitragVerfasst: Fr 15.09.06 11:58 
Kann mir jmd die letzten drei Sachen erklären bitte!
Also den Anfang hab ich verstanden, nur durch das Array und das Hinzufügen von variablen Werten steig ich nicht durch.

Und wie mache ich, dass er, wenn man die Checkbox erneut anklickt, also checked auf false setzt, dass er dann den Wert wieder von der Variable abzieht??? Hatte ich vergessen oben dazu zu schreiben.
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Fr 15.09.06 12:06 
Also, die Sache mit den Arrays erkläre ich Dir, aber wie man den Wert wieder abzieht, da must Du schon alleine drauf kommen.

Du kannst natürlich deine Variablen A...F (oder wie auch immer die heißen) behalten, aber wenn man auf bestimmte Variablen in Abhängigkeit eines Wertes zugreifen will, dann verwendet man den sog. 'indirekten' oder 'indizierten' Zugriff. Du kannst deine Freunde der Reihe nach aufstellen und jeden mit seinem Namen anreden. Klar, so macht man das bei Freunden auch. Du kannst aber auch einfach auf 'den 3. von Links' Bezug nehmen. Oder, wenn immer von links gezählt wird, eben nur 'der 3.' sagen.

Ähnlich ist das mit den Arrays und den individuellen Variablen. Nur während auch der 3.Freund immer noch Egon ist, verhält sich das bei den Variablen/Arrays doch etwas anders.

Stell Dir einfach vor, ein Array [1..10] sind einfach 10 Variablen nebeneinander (sind sie ja im Speicher wirklich) und Du kannst nun per MyArray[1] auf das 1., per MyArray[2] auf das 2., aber eben auch (sei i mal eine Integer-Variable) auf das i.te Element zugreifen, nämlich mit MyArray[i].

Dafür gibt es übrigens eine ganz gute Online-Hilfe, sowie diverse Tutorials hier im Forum

_________________
Na denn, dann. Bis dann, denn.
Gahero Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 193

Win Vista HP 64bit
Delphi 2007 Pro
BeitragVerfasst: Fr 15.09.06 12:39 
Ja ok das habe ich verstanden, aber wie hast du das mit den verschiedenen Werten gemacht, die dazu addiert werden?

Edit: Ahh ichs versteh es!!! Thx

Muss ich das jetzt für jede Checkbox machen???
Oder geht das auch anders?


Edit2: Ok jetzt hab ich es wirklich :-)!!! Ich machs mit Findkomponent und einer For Schleife. Mal sehen ob das geht.
oldmax
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 380


D3 Prof, D4 Prof
BeitragVerfasst: Fr 15.09.06 15:40 
Hi
Hoffentlich ist's nicht zuviel der Hilfe, aber wer so nachfragt, wo und wie Variablen deklariert werden...
Also ich denke, ein klein wenig mehr Hilfe tut da doch gut..
Also, ich habe einfach mal eine Form genommen, ein Editfeld eingefügt und ein paar Checkboxen, die Anzahl ist überhaupt nicht wichtig.
Dann habe ich in die Form einen Doppelclick getätigt und erhalte diese Procedure:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TForm1.FormCreate(Sender: TObject);
begin
   Counter :=0;                         // das muß eingetragen werden. Startwert der Variablen
   Edit1.Text:=IntToStr(Counter);       // das auch, damit ich den Wert der Variablen seh, 
end;

So, die Zeilen Counter := und Edit1.Text:= habe ich eingefügt. Was dieses InttoStr bewirkt, das lies bitte in der Delphi-Hilfe nach.

Nun mache ich einen Doppelclick in eine der Checkboxen und erhalte die Procedure Checkbox1Click
Diese ergänze ich wie folgt:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm1.CheckBox1Click(Sender: TObject); // Das Click-Ereignis auf die Checkbox
                                                  // Sender ist das Objekt, welches dieses Ereignis auslöst
begin                                             // hiernach muß ich meinen Code eintragen
  if Sender is TCheckbox then                     // Hier frage ich ab, ob das Ereignis von einer Checkbox ist
  begin
    if (Sender as TCheckbox).Checked  then Counter:=Counter+(Sender as TCheckbox).Tag // und addiere den Wert in Tag
    else Counter:=Counter-(Sender as TCheckbox).Tag;                                  // oder subtrahiere 
  end;
   Edit1.Text:=IntToStr(Counter);                 // und schreibe den Wert in das Editfeld zur Ansicht.
end;

Diese Procedure trage ich bei allen Checkboxen in die Ereignisroutine ein, einfach, indem ich sie im Objektinspektor aus der Auswahlliste hole. (Oberinspektor Ereignisse onClick)
Den Tag setzt du für alle deine Checkboxen auf deine gewünschten Werte und fertig.
Das weitere Drumherum wird dir jetzt wieder etwas mehr Spaß machen.
Doch halt, woher kommt die Variable Counter ? Auch das ist schnell erklärt: diese trägst du im Abschnit Var unter die Variable deiner Form ein

ausblenden Delphi-Quelltext
1:
2:
3:
var
  Form1: TForm1;       // das steht bereits im Code
  Counter : Integer;   // hier definierst du deine Variable

und nun mach was draus, auch kleine Schritte bewältigen einen weiten Weg.

Vielleicht sollte ich noch ein paar Worte dazu sagen, warum die Ereignisroutine so unterschiedlich funktionieren kann. Nun ja, über den Sender wird mitgeteilt, welche Checkbox das Ereignis ausgelöst hat und dann ist natürlich der Tag der entsprechenden Checkbox bekannt. Gut, zu Fuß könnt ich's auch nicht so schnell programmieren, daher merk dir einfach: Jedes Objekt sendet Botschaften aus und teilt sich selber mit:
Hallo, ich die Checkbox0815 hab einen Click und nun braucht der, der das hört nur nachzusehen, was hat die Checkbox0815 noch so alles zu bieten...
Besser erklären kann ich's im Moment nicht
Gruß oldmax

_________________
Zier dich nich so, ich krieg dich schon....
Gahero Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 193

Win Vista HP 64bit
Delphi 2007 Pro
BeitragVerfasst: Fr 15.09.06 15:52 
Sag ma kann man sich die erste If Abfrage nicht schenken, weil es ja eine Checkbox ist?
oldmax
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 380


D3 Prof, D4 Prof
BeitragVerfasst: Fr 15.09.06 16:26 
Hi
Möglich, das die erste If-Abfrage über ist, aber ich hab das irgendwann einmal in irgendeinem Beispiel der Delphi-Hilfe gesehen und daher hab ich's bisher immer übernommen. Es schadet nicht, und die Geschwindigkeit wird wohl auch nicht unbedingt darunter leiden...
Allerdings, was wär, wenn tatsächlich hier ein Ereignis eines Button oder Listfeldes aufkreuzt und die Ereignisroutine plötzlich eine Eigenschaft möchte, die gar nicht existiert ? Daher bleib ich erst mal bei dieser "Sicherheitsabfrage"
Gruß oldmax

_________________
Zier dich nich so, ich krieg dich schon....
Gahero Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 193

Win Vista HP 64bit
Delphi 2007 Pro
BeitragVerfasst: Fr 15.09.06 17:23 
So hab mir jetzt ne Stunde Gedanken darüber gemacht und hier ist meine Lösung:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure TForm1.Button1Click(Sender: TObject);

var
  Chk: TCheckbox;
  i: integer;
  counter: integer;

begin
  for i := 1 to 4 do
  begin
    Chk := TCheckbox(FindComponent('Checkbox' + InttoStr(i)));
    if Chk.Checked then
      Counter := Counter + Chk.Tag
    else Counter := Counter - Chk.Tag;
  end;

Edit1.Text:=InttoStr(Counter);

end;


Jetzt habe ich das Problem, das er auch abzieht wenn er es garnicht soll. Hat da jmd ne idee zu?
Raffo
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 300



BeitragVerfasst: Fr 15.09.06 18:54 
Hi, am besten Du schickst mal dein ganzes Projekt hier in den Raum, für mich sieht das alles sehr kompliziert aus - und ich hege den Verdacht, ob man das nicht alles mit einer TCheckListBox machen könnte. Ansonsten würde ich normalerweise den Zähler zunächst auf NULL stellen, und nur die "gecheckten" ...Boxen zählen, und nicht "...else ... -1".

Lass mal dein Projekt im Ganzen sehen.
oldmax
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 380


D3 Prof, D4 Prof
BeitragVerfasst: Fr 15.09.06 19:53 
Hi Gahero
Na ich nochmal.
Zitat:
Jetzt habe ich das Problem, das er auch abzieht wenn er es garnicht soll. Hat da jmd ne idee zu?

Das versteh ich jetzt aber nicht so ganz. Da geb ich dir schon den kompletten Code :shock: und du beschwerst dich immer noch, weil dein Ansatz nicht geht. :roll:
Ok, warum nimmst du diese For-Schleife ? Warum ein Extra-Button. Ist das eine Bedingung ? Das kann ja so auch nicht funktionieren, zumindest nicht so, wie du es ursprünglich beschrieben hast. Das mit FindComponent ist eine schöne Sache und sicherlich hast du auch die richtigen Checkboxen "erwischt", aber niemand hindert dich, dein Button mehrmals hintereinander zu drücken und dann rechnest du jedes mal eins weg, zwei dazu. Also, vergiß deine Schleife und denk darüber nach, welche Procedure angesprochen wird, wenn du eine Checkbox anklickst......
So, das hätten wir, denn wenn du sie anklickst, wird sie zu Checked oder eben nicht, also 5 dazu oder 5 weg. Was anderes geht gar nicht. Und wenn du nun allen Checkboxen die gleiche Routine zuweist, brauchst du sie auch nur 1 mal zu schreiben und es funktioniert bei 5 oder 100 Checkboxen immer nach der gleichen Methode. Ach ja, der Tag, die Information, ob 5 oder 1 oder irgendwas hinzu- oder abgezogen werden soll. Ja, den bringt der Sender doch mit. Wenn einer bei dir in der Klasse ruft, dann ist es ein Ruf eines Schülers, mal so ganz allgemein. Aber wenn er dazu sagt, wer er ist, kennst du seine Haarfarbe, sein Geschlecht und auch, ob er kumme Beine hat..., du braucht ihn gar nicht einmal zu sehen. :wink:

Na, nun probier schon... (ich will mich doch bestätigt wissen ...... 8) )
Gruß oldmax

_________________
Zier dich nich so, ich krieg dich schon....
Gahero Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 193

Win Vista HP 64bit
Delphi 2007 Pro
BeitragVerfasst: Fr 15.09.06 20:52 
Den Button habe ich genommen, weil er so wieso von Anfang schon im Projekt vorgesehen war.
Außerdem habe ich keine Lust für 104 Checkboxen (so viele sind es nämlich) die Prozedur zu kopieren.
Und wegen dem immer wieder drücken bau ich einfach ein, dass er den counter auf 0 setzt (am Anfang).
Deine Idee mit dem mod und div kommt auch noch da rein und die Subtraktion nehm ich raus. Fertig!
Werde das Ergebnis hier noch posten.

Edit1: So neuer Versuch:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TForm1.Button1Click(Sender: TObject); // Rechenbutton

var
  Chk: TCheckbox;
  n, i, d: integer;
  ChArray: array[1..5of Integer;

begin
  for n := 1 to 4 do
  begin
    Chk := TCheckbox(FindComponent('Checkbox' + IntToStr(n)));
    if Chk.Checked then
    i := TCheckBox(FindComponent('Checkbox' + IntToStr(n))).Tag;
    d := i mod 100;
    i := i div 100;
    ChArray[i] := ChArray[i] + d;
  end;
end;


Aber er sagt jetzt bei "ChArray[i] := ChArray[i] + d;", dass i nicht initialisiert ist. Hat jmd Ahnung warum? I wird ja weiter oben ein Wert zugeordnet.


Zuletzt bearbeitet von Gahero am Fr 15.09.06 21:43, insgesamt 3-mal bearbeitet
jakobwenzel
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1889
Erhaltene Danke: 1

XP home, ubuntu
BDS 2006 Prof
BeitragVerfasst: Fr 15.09.06 21:07 
Wer lesen kann ist klar im Vorteil:

user profile iconoldmax hat folgendes geschrieben:
Und wenn du nun allen Checkboxen die gleiche Routine zuweist, brauchst du sie auch nur 1 mal zu schreiben und es funktioniert bei 5 oder 100 Checkboxen immer nach der gleichen Methode.

_________________
I thought what I'd do was, I'd pretend I was one of those deaf-mutes.