Autor |
Beitrag |
Gahero
      
Beiträge: 193
Win Vista HP 64bit
Delphi 2007 Pro
|
Verfasst: 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
      
Beiträge: 190
Win XP
Delphi 7 PE, C++ (Dev-C++), HTML+PHP (Dreamweaver MX), JavaScript(MS FrontPage)
|
Verfasst: Di 12.09.06 17:33
Ja, du könntest eine Schleife durchlaufen lassen, wieviele sind es denn ungefähr?
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: 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
      
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)
|
Verfasst: 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
      
Beiträge: 190
Win XP
Delphi 7 PE, C++ (Dev-C++), HTML+PHP (Dreamweaver MX), JavaScript(MS FrontPage)
|
Verfasst: Di 12.09.06 17:45
Ja ich denk aba mal das er es so meint:
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 raziel: Code- durch Delphi-Tags ersetzt
|
|
Gahero 
      
Beiträge: 193
Win Vista HP 64bit
Delphi 2007 Pro
|
Verfasst: 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
      
Beiträge: 190
Win XP
Delphi 7 PE, C++ (Dev-C++), HTML+PHP (Dreamweaver MX), JavaScript(MS FrontPage)
|
Verfasst: Mi 13.09.06 21:37
|
|
Gahero 
      
Beiträge: 193
Win Vista HP 64bit
Delphi 2007 Pro
|
Verfasst: Do 14.09.06 17:57
Ja, aber es soll ja nicht immer derselbe Wert sein, der dazu addiert wird.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: 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:
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.
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:
Delphi-Quelltext 1:
| CheckBox.Tag := 10000 * VariablenIndex + Zähler; |
Das Ereignis wird nur ein bisserl komplexer;
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 
      
Beiträge: 193
Win Vista HP 64bit
Delphi 2007 Pro
|
Verfasst: 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
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: 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 
      
Beiträge: 193
Win Vista HP 64bit
Delphi 2007 Pro
|
Verfasst: 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
      
Beiträge: 380
D3 Prof, D4 Prof
|
Verfasst: 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:
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TForm1.FormCreate(Sender: TObject); begin Counter :=0; Edit1.Text:=IntToStr(Counter); 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:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TForm1.CheckBox1Click(Sender: TObject); begin if Sender is TCheckbox then begin if (Sender as TCheckbox).Checked then Counter:=Counter+(Sender as TCheckbox).Tag else Counter:=Counter-(Sender as TCheckbox).Tag; end; Edit1.Text:=IntToStr(Counter); 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
Delphi-Quelltext 1: 2: 3:
| var Form1: TForm1; Counter : Integer; |
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 
      
Beiträge: 193
Win Vista HP 64bit
Delphi 2007 Pro
|
Verfasst: Fr 15.09.06 15:52
Sag ma kann man sich die erste If Abfrage nicht schenken, weil es ja eine Checkbox ist?
|
|
oldmax
      
Beiträge: 380
D3 Prof, D4 Prof
|
Verfasst: 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 
      
Beiträge: 193
Win Vista HP 64bit
Delphi 2007 Pro
|
Verfasst: Fr 15.09.06 17:23
So hab mir jetzt ne Stunde Gedanken darüber gemacht und hier ist meine Lösung:
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
      
Beiträge: 300
|
Verfasst: 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
      
Beiträge: 380
D3 Prof, D4 Prof
|
Verfasst: 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  und du beschwerst dich immer noch, weil dein Ansatz nicht geht.
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.
Na, nun probier schon... (ich will mich doch bestätigt wissen ......  )
Gruß oldmax
_________________ Zier dich nich so, ich krieg dich schon....
|
|
Gahero 
      
Beiträge: 193
Win Vista HP 64bit
Delphi 2007 Pro
|
Verfasst: 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:
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); var Chk: TCheckbox; n, i, d: integer; ChArray: array[1..5] of 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
      
Beiträge: 1889
Erhaltene Danke: 1
XP home, ubuntu
BDS 2006 Prof
|
Verfasst: Fr 15.09.06 21:07
Wer lesen kann ist klar im Vorteil:
oldmax 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.
|
|
|