![]() |
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
Aber gut sei's drum. gruss |
AW: Elemente aus TStringList in Laufzeit entfernen
Jetzt mal Butter bei die Fische.
Wir wollen dir alle nur helfen. Wir wissen sicher auch, dass das, was wir hier von uns geben und dir empfehlen, nicht leicht für dich ist. Aber nur weil man etwas nicht gleich versteht sollte man doch nicht bei einer Lösung die nachgewiesenermaßen schlecht ist. Wenn euch nahegelegt wurde das mit einer StringListe zu machen, dann ist das nur eine Empfehlung. Aber du kannst es sehr viel besser machen. Ich habe dir ein komplettes Beispiel gepostet und Holger hat es komplettiert. Teste es doch einfach aus. Du wirst sehen wie unglaublich leichter alles wird wenn du nur auf uns hörst. Vergiss die StringListe. Die scheinst du nicht wirklich verstanden zu haben. Das, mit dem Vergessen, haben dir hier auch schon mehrere gesagt. PS: ich würde mir an dieser Stelle einen schönen und ausführlichen Roman von Michael wünschen =) |
AW: Elemente aus TStringList in Laufzeit entfernen
@DieDolly
Den Fehler mit der falschen Freigabe kann man bei Klassen genauso machen, es geht erstmal um ein Grundsätzliches Verständnis dafür, wann man etwas erstellt und wann man es wieder freigibt. Würden wir das mit Klassen machen und die Klasse dann, wenn wir in der letzten Methode, in der wir sie benötigen, freigeben, während wir sie noch benötigen, hätten wir exakt das gleiche Problem. Abgesehen davon kennen wir nicht die Vorgaben, die für das Schulprojekt gestellt wurden. Wenn es da z. b. hieße: "Erstelle einen Vokalbeltrainer mit Hilfe einer Stringliste", dann helfen wiederholte Hinweise darauf, dass man das alles irgendwie auch ganz anders machen kann, nicht. Ich halte es für wichtiger, erstmal mit dem in Delphi von Haus aus vorhandenen klarzukommen. Solange das nicht funktioniert, werden auch die besten selbsterstellten Klassenbibliotheken nicht fertig, weil noch Grundlagenwissen fehlt. Wenn das da ist, kann man anfangen zu überlegen, ob das Problem nicht deutlich eleganter gelöst werden könnte. |
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
Sei bitte etwas Verständlichsvoller wenn er nicht einmal weis was free bedeutet Zitat:
Nicht das er hier noch die Lust verliert weiterhin zu fragen. Zitat:
gruss |
AW: Elemente aus TStringList in Laufzeit entfernen
Was das Free bedeutet steht mindestens 1x auf den letzten paar Seiten. Ansonsten hilft doch immer F1.
|
AW: Elemente aus TStringList in Laufzeit entfernen
Hallöle...8-)
Zitat:
Ich tippe darauf, weil z.B. die Bezeichner nicht dem aktuellem Standard entsprechen. Letztendlich ist es jedem seine Entscheidung wie man es macht...mein Tipp wäre aber, dich von Anfang an an dem offiziellen Styleguide zu orientieren. ![]() oder in deutsch ![]() [meine Meinung] Was mich stört: :wink: * Groß/Kleinschreibung der Bezeichner * leilweise nicht sprechende Namen jpg besser ImageAnswer ...auch Form1 kann anders heißen * Unterstriche in den Namen in Verbindung des Types des Controls :kotz: L_CorrectAnswer -> besser lblCorrectAnswer * kein korrektes try/finally * Vergleiche auf TRUE ... kann in die Hose gehen ![]() * globale Variablen [/meine Meinung] Wenn man schon am Lernen ist, dann aber richtig... |
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
OK, dann poste mal den ganzen Quellcode. Der enthält jetzt aber auch ein Haufen Grafikzeug, da ich versuche das visuell ansprechend zu gestalten ohne wirklich Ahnung von Delphi zu haben. Also das ganz ist in 3 Forms aufgeteilt. Ein Hauptmenü, einmal der Vokabeltrainer und eine Zusammenfassung am Schluss. Im Hauptmenü kann man auswählen ob man Deutsch>Englisch oder Englisch>Deutsch lernen will und wie oft eine Vokabel wiederholt werden soll. Dann startet man mit einem Button den Vokabeltrainer (zweites Fenster öffnet sich, Erstes wird geschlossen). Hier werden die Vokabeln abgefragt. Wenn man alle entsprechend der Wiederholungsanzahl richtig eingegeben hat öffnet sich das dritte Fenster (zweites schließt sich). Hier wird eine Zusammenfassung angezeigt. Wie lange man gebraucht hat, wie viele versuche man gebraucht hat... Dann soll man mit einem Button das Hauptmenü wieder öffen können um von vorn anzufangen. Hier der Quellcode für das Hauptmenü
Delphi-Quellcode:
Ja, das kann man sicherlich optimaler gestalten aber das ist in der Aufgabe nicht so wichtig (ist ja auch nur ein Schulfach, kein Informatik Studium). Ich muss aber den ganzen Quellcode in einem Vortrag erklären können.
unit U_MainMenu;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Menus; type TForm1 = class(TForm) Bt_Start: TButton; Bt_SwitchLanguage: TButton; Img_Background_01: TImage; Img_Background_02: TImage; L_HeadingMainMenu: TLabel; E_Repititions: TEdit; Img_BackgroundSwitchLanguage: TImage; L_SwitchLanguage: TLabel; E_Amount: TEdit; Img_HeadingAmountBackground: TImage; L_HeadingAmount: TLabel; Img_HeadingRepititionsBackground: TImage; L_HeadingRepititions: TLabel; procedure Bt_StartClick(Sender: TObject); procedure Bt_SwitchLanguageClick(Sender: TObject); procedure FormCreate(Sender: TObject); //procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; var GermanEnglish: Boolean; var Repititions: Byte; implementation uses U_VocabularyTraining; {$R *.dfm} procedure TForm1.Bt_StartClick(Sender: TObject); var Form2: TForm2; begin Repititions:= StrToInt(E_Repititions.Text); Form2 := TForm2.Create(Self); //Application.ShowMainForm := False; //Form1.Visible := False; try Form2.ShowModal; finally Form2.Free; end; end; procedure TForm1.Bt_SwitchLanguageClick(Sender: TObject); Begin If GermanEnglish = True Then Begin L_SwitchLanguage.Caption:='Englisch -> Deutsch'; GermanEnglish:= False; End Else Begin L_SwitchLanguage.Caption:='Deutsch -> Englisch'; GermanEnglish:= True; End; End; procedure TForm1.FormCreate(Sender: TObject); var rectangle1: TRect; color: Tcolor; CenterTextHeadingMainMenu_1, CenterTextHeadingMainMenu_2, CenterTextSwitchLanguage_1, CenterTextSwitchLanguage_2, CenterTextHeadingAmount_1, CenterTextHeadingAmount_2, CenterTextHeadingRepititions_1, CenterTextHeadingRepititions_2: Integer; begin GermanEnglish:= True; Img_Background_01.Canvas.Brush.Color:= RGB(170,220,70); Img_Background_01.Canvas.Rectangle(-1,-1,Img_Background_01.Width+1,Img_Background_01.Height+1); Img_Background_02.Canvas.Brush.Color:= RGB(170,220,70); Img_Background_02.Canvas.Rectangle(-1,-1,Img_Background_02.Width+1,Img_Background_02.Height+1); Img_BackgroundSwitchLanguage.Canvas.Brush.Color:= RGB(170,220,70); Img_BackgroundSwitchLanguage.Canvas.Rectangle(-1,-1,Img_Background_02.Width+1,Img_Background_02.Height+1); Img_HeadingAmountBackground.Canvas.Brush.Color:= RGB(170,220,70); Img_HeadingAmountBackground.Canvas.Rectangle(-1,-1,Img_Background_02.Width+1,Img_Background_02.Height+1); Img_HeadingRepititionsBackground.Canvas.Brush.Color:= RGB(170,220,70); Img_HeadingRepititionsBackground.Canvas.Rectangle(-1,-1,Img_Background_02.Width+1,Img_Background_02.Height+1); L_HeadingRepititions.Font.Name:='Helvetica LT Std'; L_HeadingRepititions.Font.Size:= 16; L_HeadingRepititions.Font.Color:= clWhite; CenterTextHeadingRepititions_1:= Form1.Width div 3; CenterTextHeadingRepititions_2:= L_HeadingRepititions.Width div 1; L_HeadingRepititions.Left:= CenterTextHeadingRepititions_1 + CenterTextHeadingRepititions_2; L_HeadingAmount.Font.Name:='Helvetica LT Std'; L_HeadingAmount.Font.Size:= 16; L_HeadingAmount.Font.Color:= clWhite; CenterTextHeadingAmount_1:= Form1.Width div 4; CenterTextHeadingAmount_2:= L_HeadingAmount.Width div 2; L_HeadingAmount.Left:= CenterTextHeadingAmount_1 - CenterTextHeadingAmount_2; E_Amount.Font.Name:='Helvetica LT Std'; E_Amount.Font.Size:= 16; E_Amount.Font.Color:= RGB(170,220,70); CenterTextHeadingAmount_1:= Form1.Width div 4; CenterTextHeadingAmount_2:= E_Amount.Width div 2; E_Amount.Left:= CenterTextHeadingAmount_1 - CenterTextHeadingAmount_2; L_HeadingMainMenu.Font.Name:='Helvetica LT Std'; L_HeadingMainMenu.Font.Size:= 24; L_HeadingMainMenu.Font.Color:= clWhite; CenterTextHeadingMainMenu_1:= Form1.Width div 2; CenterTextHeadingMainMenu_2:= L_HeadingMainMenu.Width div 2; L_HeadingMainMenu.Left:= CenterTextHeadingMainMenu_1 - CenterTextHeadingMainMenu_2; L_SwitchLanguage.Font.Name:='Helvetica LT Std'; L_SwitchLanguage.Font.Size:= 16; L_SwitchLanguage.Font.Color:= clWhite; CenterTextSwitchLanguage_1:= Form1.Width div 2; CenterTextSwitchLanguage_2:= L_SwitchLanguage.Width div 2; L_SwitchLanguage.Left:= CenterTextSwitchLanguage_1 - CenterTextSwitchLanguage_2; E_Repititions.Text:= '3'; end; end. Und hier der Quellcode zum Vokabeltrainer:
Delphi-Quellcode:
Das letzte Fenster hat noch nicht viel Code. In Delphi ist der Code deutlich übersichtlicher, da um Begin und End noch eine Farbige Klammer ist.
unit U_VocabularyTraining;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, JPEG; type TForm2 = class(TForm) Bt_Compare: TButton; E_UserGuess: TEdit; Img_FeedBack: TImage; Img_Background_04: TImage; Img_Background_03: TImage; L_HeadingTrainer: TLabel; L_RemainingWords: TLabel; Img_BackgroundUnknownWord: TImage; L_UnknownWord: TLabel; L_CorrectAnswer: TLabel; Img_BackgroundCorrectAnswer: TImage; Img_FlagQuestion: TImage; Img_FlagAnswer: TImage; L_HeadingTrainerDescription: TLabel; procedure FormCreate(Sender: TObject); procedure Bt_CompareClick(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } public { Public declarations } var Vocabulary: TStringList; RandomNumber, Abfragen: Integer; jpgFlag, jpgCorrect, jpgWrong: TJpegImage; StartTime: TDateTime; Duration: TDateTime; end; var Form2: TForm2; implementation uses U_MainMenu, U_Conclusion; {$R *.dfm} procedure TForm2.Bt_CompareClick(Sender: TObject); var Input: String; Answer, RepetitionCheck: Integer; Form3: TForm3; Begin If Vocabulary.Count > 0 Then Begin If GermanEnglish = True Then Begin Input:= E_UserGuess.Text; E_UserGuess.Text:= ''; Answer:=AnsiCompareStr(Vocabulary.Names[RandomNumber], Input); If Answer=0 Then Begin L_CorrectAnswer.Caption:=''; Img_FeedBack.Picture.Bitmap.Assign(jpgCorrect); Vocabulary.Delete(RandomNumber); End Else Begin L_CorrectAnswer.Caption:='Deine Antwort: '+(Input)+' '+'Richtige Antwort: '+(Vocabulary.Names[RandomNumber]); Img_FeedBack.Picture.Bitmap.Assign(jpgWrong); End; RepetitionCheck:=RandomNumber; While RepetitionCheck = RandomNumber Do RandomNumber:=random(Vocabulary.Count); try L_UnknownWord.Caption:= Vocabulary.ValueFromIndex[RandomNumber]; L_RemainingWords.Caption:= 'Verbleibende Vokabeln: '+IntToStr(Vocabulary.Count); L_RemainingWords.Font.Name:='Helvetica LT Std'; L_RemainingWords.Font.Size:= 16; L_RemainingWords.Font.Color:= RGB(170,220,70); finally end; end Else Begin Input:= E_UserGuess.Text; E_UserGuess.Text:= ''; Answer:=AnsiCompareStr(Vocabulary.ValueFromIndex[RandomNumber], Input); If Answer=0 Then Begin L_CorrectAnswer.Caption:=''; Img_FeedBack.Picture.Bitmap.Assign(jpgCorrect); jpgCorrect.free; Vocabulary.Delete(RandomNumber); End Else Begin L_CorrectAnswer.Caption:='Deine Antwort: '+(Input)+' '+'Richtige Antwort: '+(Vocabulary.ValueFromIndex[RandomNumber]); Img_FeedBack.Picture.Bitmap.Assign(jpgWrong); jpgWrong.free; End; RepetitionCheck:=RandomNumber; While RepetitionCheck = RandomNumber Do RandomNumber:=random(Vocabulary.Count); try L_UnknownWord.Caption:= Vocabulary.Names[RandomNumber]; L_RemainingWords.Caption:= 'Verbleibende Vokabeln: '+IntToStr(Vocabulary.Count); L_RemainingWords.Font.Name:='Helvetica LT Std'; L_RemainingWords.Font.Size:= 16; L_RemainingWords.Font.Color:= RGB(170,220,70); finally end; End; End Else Begin FormDestroy(Vocabulary); End; End; procedure TForm2.FormCreate(Sender: TObject); var CenterTextHeadingTrainer_1, CenterTextHeadingTrainer_2, CenterTextHeadingTrainerDescription_1, CenterTextHeadingTrainerDescription_2, CenterTextRemainingWords_1, CenterTextRemainingWords_2: Integer; begin //Color := RGB(170,220,70); //Hintergrund grün //P_Question.Color := RGB(255,255,255); //Fragefeld Hintergrund weiß //P_Answer.Color := RGB(255,255,255); //Antwortfeld Hintergrund weiß Img_Background_03.Canvas.Brush.Color:= RGB(170,220,70); Img_Background_03.Canvas.Rectangle(-1,-1,Img_Background_03.Width+1,Img_Background_03.Height+1); Img_Background_04.Canvas.Brush.Color:= RGB(170,220,70); Img_Background_04.Canvas.Rectangle(-1,-1,Img_Background_04.Width+1,Img_Background_04.Height+1); Img_BackgroundUnknownWord.Canvas.Brush.Color:= RGB(170,220,70); Img_BackgroundUnknownWord.Canvas.Rectangle(-1,-1,Img_BackgroundUnknownWord.Width+1,Img_BackgroundUnknownWord.Height+1); Img_BackgroundCorrectAnswer.Canvas.Brush.Color:= RGB(220,220,220); Img_BackgroundCorrectAnswer.Canvas.Rectangle(-1,-1,Img_BackgroundCorrectAnswer.Width+1,Img_BackgroundCorrectAnswer.Height+1); L_HeadingTrainer.Font.Name:='Helvetica LT Std'; L_HeadingTrainer.Font.Size:= 24; L_HeadingTrainer.Font.Color:= clWhite; CenterTextHeadingTrainer_1:= Form1.Width div 2; CenterTextHeadingTrainer_2:= L_HeadingTrainer.Width div 2; L_HeadingTrainer.Left:= CenterTextHeadingTrainer_1 - CenterTextHeadingTrainer_2; L_HeadingTrainerDescription.Font.Name:='Helvetica LT Std'; L_HeadingTrainerDescription.Font.Size:= 16; L_HeadingTrainerDescription.Font.Color:= clWhite; CenterTextHeadingTrainerDescription_1:= Form1.Width div 5; CenterTextHeadingTrainerDescription_2:= L_HeadingTrainerDescription.Width div 2; L_HeadingTrainerDescription.Left:= CenterTextHeadingTrainerDescription_1 - CenterTextHeadingTrainerDescription_2; L_RemainingWords.Caption:= 'Verbleibende Vokabeln: 3'; L_RemainingWords.Font.Name:='Helvetica LT Std'; L_RemainingWords.Font.Size:= 16; L_RemainingWords.Font.Color:= RGB(170,220,70); CenterTextRemainingWords_1:= Form1.Width div 2; CenterTextRemainingWords_2:= L_RemainingWords.Width div 2; L_RemainingWords.Left:= CenterTextRemainingWords_1 - CenterTextRemainingWords_2; jpgCorrect:= TJpegImage.Create; jpgCorrect.LoadFromFile('True.jpg'); jpgWrong:= TJpegImage.Create; jpgWrong.LoadFromFile('False.jpg'); StartTime := Now; Vocabulary:= TStringList.Create; Vocabulary.LoadFromFile('Vocabulary.txt'); RandomNumber:= random(Vocabulary.Count); L_RemainingWords.Caption:= 'Verbleibende Vokabeln: '+IntToStr(Vocabulary.Count); If GermanEnglish = True Then try L_HeadingTrainerDescription.Caption:= 'Deutsch -> Englisch | '+IntToStr(Repititions)+' Abfragen | 10 Vokabeln'; jpgFlag := TJpegImage.Create; jpgFlag.LoadFromFile('GermanFlag.jpg'); Img_FlagQuestion.Picture.Bitmap.Assign(jpgFlag); jpgFlag.free; jpgFlag := TJpegImage.Create; jpgFlag.LoadFromFile('BritishFlag.jpg'); Img_FlagAnswer.Picture.Bitmap.Assign(jpgFlag); jpgFlag.free; L_UnknownWord.Caption:= Vocabulary.ValueFromIndex[RandomNumber]; L_CorrectAnswer.Caption:= ''; finally end Else try L_HeadingTrainerDescription.Caption:='Englisch -> Deutsch | '+IntToStr(Repititions)+' Abfragen | 10 Vokabeln'; jpgFlag := TJpegImage.Create; jpgFlag.LoadFromFile('BritishFlag.jpg'); Img_FlagQuestion.Picture.Bitmap.Assign(jpgFlag); jpgFlag.free; jpgFlag := TJpegImage.Create; jpgFlag.LoadFromFile('GermanFlag.jpg'); Img_FlagAnswer.Picture.Bitmap.Assign(jpgFlag); jpgFlag.free; L_UnknownWord.Caption:= Vocabulary.Names[RandomNumber]; L_CorrectAnswer.Caption:= ''; finally End; end; procedure TForm2.FormDestroy(Sender: TObject); begin Vocabulary.Free; jpgWrong.free; jpgCorrect.free; Form3 := TForm3.Create(self); try Form3.ShowModal; finally Form3.Free; end; end; end. |
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
Ich verwende die variable Boolean schon seit ewigen gedenken nicht mehr. (abgesehen von VB5 und aufwärts) Wenn schon dann LongBool oder die verkürzte form BOOL = LongBool. In der heutigen zeit noch auf Boolean zu vergleichen ist für mich genauso ein Unding. Aber gut gehört nicht direkt zum Thema. gruss |
AW: Elemente aus TStringList in Laufzeit entfernen
Die Stringliste wird im TForm2.FormCreate erstellt und in TForm2.FormDestroy freigeben.
Eine Freigabe irgendwo "unterwegs" ist schlicht und einfach falsch. Auch der Aufruf von FormDestroy ist nicht wirklich zielführend, da hier alles ausgeführt wird, was bei der Freigabe des Formulares erforderlich ist. Im FormDestroy ein weiteres Formular zu öffnen, halte ich nicht für sinnvoll. Mache Dir bitte eine Methode, die zum Ende, wenn das Vokabeltraining erfolgreich abgeschlossen wurde, aufgerufen wird. In der Methode kannst Du dann das Form3 erstellen und anzeigen. FormDestroy enthält nur dashier:
Delphi-Quellcode:
In einer weiteren Methode, z. B.: Erfolgsmeldung, steht dann sowas in der Art:
procedure TForm2.FormDestroy(Sender: TObject);
begin Vocabulary.Free; jpgWrong.free; jpgCorrect.free; end;
Delphi-Quellcode:
Oben in der Unit musst Du dann noch etwas ergänzen:
procedure TForm2.Erfolgsmeldung(Sender: TObject);
begin Form3 := TForm3.Create(self); try Form3.ShowModal; finally Form3.Free; end; end;
Delphi-Quellcode:
An der Stelle, an der Du momentan
...
procedure FormCreate(Sender: TObject); procedure Bt_CompareClick(Sender: TObject); procedure Erfolgsmeldung(Sender: TObject); procedure FormDestroy(Sender: TObject); private ...
Delphi-Quellcode:
stehen hast, ruftst Du dann die Methode
FormDestroy(Vocabulary);
Delphi-Quellcode:
auf.
Erfolgsmeldung(self);
Danach sollte (hoffentlich) das "unmotivierte" Beenden des Programmes oder die Folgefehler der Stringlistenfreigabe, behoben sein. Dafür Zitat:
Klar kann man da noch was verbesssern, aber mir ist im Laufe meines Lebens noch kein Programm untergekommen, an dem man nicht noch irgendwas verbessern könnte. Mit der Zeit wird man besser und mag eventuell das eine oder andere, was man gemacht hat, nicht mehr wirklich anschauen. Sorg' erstmal dafür, dass das Programm so funktioniert, wie Du Dir es vorstellst. Dann schaust Du, ob es irgendwelche Quelltexte gibt, die in (fast) identischer Form, mehrfach vorkommen. Daraus machst Du dann Methoden, die Du entsprechend aufrufst. Dadurch wird der Quelltext leichter lesbar. Ungetesteter Vorschlag: aus
Delphi-Quellcode:
machen wir sowas in der Art:
Img_Background_01.Canvas.Brush.Color:= RGB(170,220,70);
Img_Background_01.Canvas.Rectangle(-1,-1,Img_Background_01.Width+1,Img_Background_01.Height+1); Img_Background_02.Canvas.Brush.Color:= RGB(170,220,70); Img_Background_02.Canvas.Rectangle(-1,-1,Img_Background_02.Width+1,Img_Background_02.Height+1); Img_BackgroundSwitchLanguage.Canvas.Brush.Color:= RGB(170,220,70); Img_BackgroundSwitchLanguage.Canvas.Rectangle(-1,-1,Img_Background_02.Width+1,Img_Background_02.Height+1); Img_HeadingAmountBackground.Canvas.Brush.Color:= RGB(170,220,70); Img_HeadingAmountBackground.Canvas.Rectangle(-1,-1,Img_Background_02.Width+1,Img_Background_02.Height+1); Img_HeadingRepititionsBackground.Canvas.Brush.Color:= RGB(170,220,70); Img_HeadingRepititionsBackground.Canvas.Rectangle(-1,-1,Img_Background_02.Width+1,Img_Background_02.Height+1);
Delphi-Quellcode:
und statt obiger vielen Zeilen, wird daraus dann sowas in der Art:
procedure TForm1.DefaultImg(Img1 : TImage; Img2 : TImage);
begin Img1.Canvas.Brush.Color := RGB(170,220,70); Img1.Canvas.Rectangle(-1,-1,Img2.Width + 1,Img2.Height + 1); end;
Delphi-Quellcode:
In den ersten beiden Zeilen wird die Methode mit zwei identischen Parametern aufgerufen, das kann man sicherlich auch noch verbessern, in dem man eine überladene Methode erstellt, ... aber das kommt später ;-)
DefaultImg(Img_Background_01,Img_Background_01);
DefaultImg(Img_Background_02,Img_Background_02); DefaultImg(Img_BackgroundSwitchLanguage,Img_Background_02); DefaultImg(Img_HeadingAmountBackground,Img_Background_02); DefaultImg(Img_HeadingRepititionsBackground,Img_Background_02); |
AW: Elemente aus TStringList in Laufzeit entfernen
Vielen Dank, jetzt bin ich schon ein großen Schritt weiter. Ich hab jetzt auch das Problem des Absturzes ausgemacht.
Code:
Ich wollte verhindern, dass dieselbe Vokabel zwei mal hintereinander abgefragt wird und hab mir damit ne Endlosschleife gebaut, wenn nur noch eine Vokabel vorhanden ist. :oops:
RepetitionCheck:=RandomNumber;
While RepetitionCheck = RandomNumber Do RandomNumber:=random(Vocabulary.Count); Wie erfahre ich denn jetzt welche die Letzte übrig gebliebene Vokabel ist, nachdem alle anderen zufällig mit .Delete entfernt wurden? Ich dachte sie müsste den Index 0 haben, das gibt aber ein "out of bounds" zurück. |
AW: Elemente aus TStringList in Laufzeit entfernen
Wenn die Vokabeln, nachdem sie erfolgreich "erraten" wurden, aus der Liste entfernt werden, ist Count irgendwann = 0. Dann ist die Liste leer.
Ist Count = 1, ist nur noch eine Vokabel enthalten, dann läuft die Schleife wirklich weiter, bis der Strom ausfällt ;-) Wenn man per Index auf 'ne Stringliste zugreift, sollte man ggfls. vorher abfragen, ob Index >= 0 und kleiner Count ist. Nur dann "greift" man auf einen vorhandenen Wert zu. Wenn also nur noch eine Vokabel in der Liste ist, könnte man z. B. sowas in der Art machen:
Delphi-Quellcode:
if Vocabulary.Count = 0 then begin
ShowMessage(Format('Die letzte Vokabel ist: %s',[Vocabulary.ValueFromIndex[0]]); // Oder hier das "Fertigformular" (Form3) aufrufen ... end else begin RepetitionCheck:=RandomNumber; While RepetitionCheck = RandomNumber Do RandomNumber:=random(Vocabulary.Count); ... |
AW: Elemente aus TStringList in Laufzeit entfernen
Wenn aus der Liste ein zufälliges Element ausgewählt wurde, dann wird es auch aus der Liste entfernt.
Wozu gibt es jetzt diesen RepetitionCheck? Was nicht mehr in der Liste ist, kann auch nicht wieder gezogen werden. Am Index 17 steht ein anderer Wert als vorher (weil die 17 wurde ja entfernt). Wo wäre also das Problem, wenn zweimal hintereinander die 17 gezogen wird? |
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
|
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
|
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
Es fällt mir aber sehr schwer mich in das System reinzudenken und ich kann (und möchte auch nicht) einfach Quellcode kopieren, da ich jede Zeile Quellcode in einem Vortrag erklären können muss. Mir liegt das Programmieren nicht so, bin eher der Grafiker. Ich finde es aber interessant und will eine gute Arbeit abliefern. |
AW: Elemente aus TStringList in Laufzeit entfernen
Dann mal einen Vorschlag ohne Klassen.
Lade die Liste und arbeite diese ab (Eintrag wird sofort gelöscht). Wenn die leer ist dann wieder aus der Datei laden, und nochmal durch, laden und nochmal durch und fertig. |
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
Wenns dir schwer fällt dich darein zu denken, dann nutz doch Google oder F1 oder die online Embarcadero Hilfe oder das Forum oder oder. Du erfindest das Rad neu, und nicht nur einmal. Nutzen von Klassen und Listen hat hier nur Vorteile denn du nutzt zusätzlich zum einmaligen Laden der Vokabeln eh eine StringListe. 2 Fliegen mit einer Klappe. |
AW: Elemente aus TStringList in Laufzeit entfernen
Dann versuche ich mal eine Erklärung.
Du hast eine Vokabel und die zugehörige Übersetzung. Weiterhin benötigst Du eine Zählung für die korrekte Übersetzung. Du könntest mit drei Arrays (Vokabel,übersetzung,zählung) arbeiten. Das ist aber arg aufwendig und fehleranfällig. Eine andere Möglichkeit wäre es ein Record zu nutzen z.b.
Delphi-Quellcode:
In diesem Falle hast Du alle notwendigen Daten in einem Datensatz zusammen gefasst. Da hast Du keinen Aufwand mit der Synchronisation.
type
myrecord = record Vokabel : string; Uebersetzung : string; Zaehler : integer; end; Jetzt packst Du die Records noch in eine Liste, die nicht nur die Daten sondern auch alle notendigen Funktionen enthält und Das halbe Programm ist fertig. Die andere Hälfte ist die Darstellung und die Benutzereingaben. Mit den Daten hast Du dann nichts mehr zu tun, da die Auswahl der Datensätze, die Zählung, die Initialisierung etc. in der Liste enthalten sind. Gruß K-H |
AW: Elemente aus TStringList in Laufzeit entfernen
Moin...:P
@KetchUp: Da keine Rückfrage aufgekommen ist, die Frage, ob du das: ![]() ...gelesen hast? |
AW: Elemente aus TStringList in Laufzeit entfernen
[OT]
Zitat:
Delphi-Quellcode:
, das für die Antwort verwendet wird
TImage
Delphi-Quellcode:
lauten.
AnswerImage
[/OT] |
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
Den Code schau ich mir erst morgen wieder an, muss noch lernen. Es sieht ja aus als komme ich um Record oder Classes nicht drum herum. |
AW: Elemente aus TStringList in Laufzeit entfernen
Moin...8-)
...alles gut. Mir ging es darum, daß man sich nicht was angewöhnt was später hinderlich ist, wenn man z.B. in ein neues Team wechselt. :wink: |
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
Ich benenne meine Labels auch mit einer Abkürzung davor lblCorrectAnswer wie man es macht bleibt jedem selbst überlassen. Letztendlich musst du selbst damit klar kommen. gruss |
AW: Elemente aus TStringList in Laufzeit entfernen
Liegt an der Art und Weise wie es einem beigebracht / vorgeschrieben wird.
Ich hab auch für labels die ich während der Laufzeit ändern muss ein "lblName" da bei mir "LName" für Lokale Dinge stehen :) An TE: Ich find es Klasse das Du Dir alles selbst erarbeiten und nichts fertiges benutzen möchtest! Aber den Tipp es über Klassen oder mindestens einen Record laufen zu lassen, darüber würde ich nochmal nachdenken. Mit dem Record ist am einfachsten in Deinem Falle zu übertragen/anzuwenden/einzubauen. Ist ja keine Kopie da Du kompletten Source dafür selbst noch anpassen müsstest wobei wir gerne helfen können :-) |
AW: Elemente aus TStringList in Laufzeit entfernen
Ok, ich versuch das jetzt mit Records. Ein Record scheint ja einfach nur den Variablennamen mit einem T davor als Datentyp zu haben. Ich hab das global so Deklariert
Delphi-Quellcode:
Compiler meckert aber. "Undeclared identifier" Wie muss ich es denn richtig machen?var VocabLanguage: TVocabLanguage;
Delphi-Quellcode:
procedure TForm2.FormCreate(Sender: TObject);
var i: Integer; begin Vocabulary:= TStringList.Create; Vocabulary.LoadFromFile('Vocabulary.txt'); RandomNumber:= random(Vocabulary.Count); L_RemainingWords.Caption:= 'Verbleibende Vokabeln: '+IntToStr(Vocabulary.Count); If GermanEnglish Then try L_HeadingTrainerDescription.Caption:= 'Deutsch -> Englisch | '+IntToStr(Repititions)+' Wiederholungen | 10 Vokabeln'; for i:= 0 to Vocabulary.Count - 1 do Begin VocabLanguage = record VocabLanguage:= TVocabLanguage.Create; VocabLanguage.English:= Vocabulary.Names[i] VocabLanguage.German:= Vocabulary.ValueFromIndex[i] VocabLanguage.SolvedCount:= 0; L_UnknownWord.Caption:= VocabLanguage.English[RandomNumber]; L_CorrectAnswer.Caption:= ''; End; finally end |
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
Ruder mal ein paar Seiten zurück und ließ dir alles durch was du finden kannst. |
AW: Elemente aus TStringList in Laufzeit entfernen
Ok, Deklaration klappt.
Delphi-Quellcode:
So ganz Unrecht hatte ich nicht, musste nur type auf record setzen.
private
{ Private declarations } public { Public declarations } type TVocab = record German, English: string; end; var Vocab: TVocab; Vocabulary: TStringList; RandomNumber, Abfragen: Integer; jpgFlag, jpgCorrect, jpgWrong: TJpegImage; StartTime: TDateTime; Duration: TDateTime; end;
Delphi-Quellcode:
Jetzt hängt es am "TVocab.Create;". Das verstehe ich noch nicht.
If GermanEnglish
Then try L_HeadingTrainerDescription.Caption:= 'Deutsch -> Englisch | '+IntToStr(Repititions)+' Wiederholungen | 10 Vokabeln'; for i:= 0 to Vocabulary.Count - 1 do Begin Vocab:= TVocab.Create; Vocab.English:= Vocabulary.Names[i]; Vocab.German:= Vocabulary.ValueFromIndex[i]; Vocab.SolvedCount:= 0; L_UnknownWord.Caption:= Vocab.English[RandomNumber]; L_CorrectAnswer.Caption:= ''; End; finally end |
AW: Elemente aus TStringList in Laufzeit entfernen
Records alleine bringen dir nichts. Du brauchst auch eine Liste wo du die reinstecken und von abfragen kannst.
|
AW: Elemente aus TStringList in Laufzeit entfernen
Als kleine Gedankenstütze, diesen Tipp mit Records meinte ich, damit es keine Kopie wird benenn halt alles um aber bleibe beim Konstrukt, das wäre eine gute Ausgangslage.
Zitat:
|
AW: Elemente aus TStringList in Laufzeit entfernen
Das ist mein momentaner Stand.
Delphi-Quellcode:
private
{ Private declarations } public { Public declarations } type TVocab = record German, English: string; Repetitions: Integer; end;
Delphi-Quellcode:
Jetzt kann ich meine Zufallszahl nicht mehr nutzen. Compiler sagt Array type required.
Input:= E_UserGuess.Text;
E_UserGuess.Text:= ''; Answer:=AnsiCompareStr(Vocabulary.Names[RandomNumber], Input); If Answer=0 Then //Antwort ist richtig Begin L_CorrectAnswer.Caption:=''; Img_FeedBack.Picture.Bitmap.Assign(jpgCorrect); //Vocabulary.Delete(RandomNumber); Vocab.Repetitions[RandomNumber]:= Vocab.Repetitions[RandomNumber] - 1; End Else //Antwort ist falsch Begin L_CorrectAnswer.Caption:='Richtig wäre: '+(Vocabulary.Names[RandomNumber]); Img_FeedBack.Picture.Bitmap.Assign(jpgWrong); Vocab.Repetitions[RandomNumber]:= RepititionValue; End; Meinst du mit in Liste packen sowas: List.Add(Vocab);? |
AW: Elemente aus TStringList in Laufzeit entfernen
Hallo,
Repetitions: Integer; Vocab.Repetitions[RandomNumber] Was soll der Compiler dann machen, wenn das mit [] auf eine Integer-Variable zugreifst. Und weiter oben hast Du ja korrekt benutzt Vocabulary[RandomNumber] Es müsste also heißen: Vocabulary[RandomNumber].Repetitions:= Vocabulary[RandomNumber].Repetitions-1; |
AW: Elemente aus TStringList in Laufzeit entfernen
Ah, Probier ich gleich mal.
|
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
Delphi-Quellcode:
Außerdem fehlt noch der wichtigste Bestandteil von Allem: die LISTE!
Vocab.Repetitions := Vocab.Repetitions - 1;
Die ganzen Records bringen dir nix wenn du keine Liste hast. |
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
Delphi-Quellcode:
Vocab[RandomNumber].Repetitions:= Vocab[RandomNumber].Repetitions - 1;
Zitat:
Delphi-Quellcode:
Dann in FormCreate:
type
TVocab = record German, English: string; List: String; Repetitions: Integer; end;
Delphi-Quellcode:
Hier wird doch für jede Vokabel der Repetitions Wert auf RepetitionValue gesetzt.Vocabulary:= TStringList.Create; Vocabulary.LoadFromFile('Vocabulary.txt'); RandomNumber:= random(Vocabulary.Count); L_RemainingWords.Caption:= 'Verbleibende Vokabeln: '+IntToStr(Vocabulary.Count); If GermanEnglish Then try for i:= 0 to Vocabulary.Count - 1 do Begin //Vocab:= TVocab.Create; Vocab.English:= Vocabulary.Names[i]; Vocab.German:= Vocabulary.ValueFromIndex[i]; Vocab.Repetitions:= RepititionValue[i]; //Vocab.SolvedCount:= 0; List.Add(Vocab); L_UnknownWord.Caption:= Vocab.English[RandomNumber]; L_CorrectAnswer.Caption:= ''; End; finally end
Code:
Also müsste er damit (wie gesagt) in OnClick vom Repepitions Wert der zufällig ausgewählten Vokabel 1 abziehen.Vocab[RandomNumber].Repetitions:= Vocab.Repetitions[RandomNumber] - 1; |
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
Zitat:
|
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
|
AW: Elemente aus TStringList in Laufzeit entfernen
Könnt ihr mir einen Tipp geben wie ich die Liste erstelle?
PS: Upps, wollte keinen Doppelpost machen. |
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
Delphi-Quellcode:
Vocabulary:= TStringList.Create;
gruss |
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
Delphi-Quellcode:
Brauche ich denn Vocab:= TVocab.Create; , List.Add(Vocab); und Vocab.SolvedCount ? Vocabulary:= TStringList.Create; Vocabulary.LoadFromFile('Vocabulary.txt'); RandomNumber:= random(Vocabulary.Count); L_RemainingWords.Caption:= 'Verbleibende Vokabeln: '+IntToStr(Vocabulary.Count); If GermanEnglish Then try for i:= 0 to Vocabulary.Count - 1 do Begin Vocab:= TVocab.Create; Vocab.English:= Vocabulary.Names[i]; //Vocab.SolvedCount:= 0; Vocab.German:= Vocabulary.ValueFromIndex[i]; Vocab.Repetitions:= RepititionValue[i]; List.Add(Vocab); L_UnknownWord.Caption:= Vocab.English[RandomNumber]; L_CorrectAnswer.Caption:= ''; End; finally end Ich müsste doch alles damit regeln können.
Delphi-Quellcode:
type
TVocab = record German, English: string; Repetitions: Integer; end; |
AW: Elemente aus TStringList in Laufzeit entfernen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:15 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz