![]() |
Label aus anderer Unit verwenden
Servus,
bin gerade dabei mir ein kleines Quiz zu erstellen und hänge gerade bei der Anzeige der Ergebnissen. Ich hab ne Unit wo die Frage angezeigt wird mit jeweils vier Buttons, siehe ![]() Nach zehn Fragen werden mir die ![]() Wenn ich jetzt auf bspw. den zweiten Button klick (Welcher die richtige Antwort hat), soll sich das Label, das anfangs die Caption "0" hat, um jeweils 1 erhöhen. Sprich, wenn ich sechs mal auf den richtigen Button geklickt hab (Von zehn Fragen), soll statt der Null eben ne Sechs stehen. Ich hab's bereits mal so ausprobiert:
Code:
Zahl ist das Label mit der Caption "0" auf der Ergebnisseite. Die Variable n: Integer; ist definiert und ich hab ebenfalls unter implementation
procedure TFrage2.SpeedButton4Click(Sender: TObject);
begin n:=strtoint(Zahl.caption); n:=n+1; Zahl.caption:=inttostr(n); uses Unitx angegeben.. jedoch bekomm ich immer die Fehlermeldung, dass "Zahl" nicht gefunden wird. Wenn ich das Label Zahl in der selben Unit erstell, wo sich die Frage befindet, erhöht sich das Ganze von 0 auf 1. Gibts irgendwie ne Möglichkeit das Problem zu beheben oder gänzlich eine andere Methode? Hab mir diverse andere Threads bereits angeschaut (Buttonclick-Zähler), jedoch kapier ich nicht ganz wie ich jene Zeilen bei mir einfügen soll, bzw. gehts bei mir ja darum, dass Label aus ner anderen Unit zu verwenden. Grüße |
AW: Label aus anderer Unit verwenden
Du musst dich dem Probelm andersherum nähern.
Also nicht, wie bekomme ich etwas in das Label rein, sondern wie kommt das Label (ok, eher die Form mit dem Label) an die Information, was es anzeigen soll. |
AW: Label aus anderer Unit verwenden
Nun, das Caption von Label enthält keine Zahl, sondern einen String. Natürlich kann man eine Zahl auch als String speichern und andersherum. Dabei muss man natürlich immer aufpassen, dass in dem String mit der Zahl immer nur Zahlen-Buchstaben vorkommen.
Betrachten wir mal dein Code
Delphi-Quellcode:
StrToInt ist schon die richtige Funktion wenn man ganz sicher weiß, dass der String eine Zahl enthält. Ansonsten kann es zu Konvertierungsfehlern kommen. Unter Umständen ist dafür die Funktion StrToIntDef angebrachter. Es gibt dann keine Fehlermeldung, dafür wird ein Ersatzwert genommen.
procedure TFrage2.SpeedButton4Click(Sender: TObject);
begin n:=strtoint(Zahl.caption); n:=n+1; Zahl.caption:=inttostr(n); Auch das n ist bei dir anscheinend global, obwohl du es zum Konvertieren nur lokal brauchst.
Delphi-Quellcode:
Vor allem beim ersten Click, wenn Label.caption z.B. leer ist, wird der leere Caption String abgefangen und als Null interpretiert.
procedure TFrage2.SpeedButton4Click(Sender: TObject);
var n: Integer; begin n := StrToIntDef(Zahl.caption, 0); n := n + 1; Zahl.caption := IntToStr(n); Willst du z.B. wissen ob es da einen Fehler gibt, kannst du in StrToIntDef einen Negativwert geben, z. B. so
Delphi-Quellcode:
. Schon kannst du erkennen ob es einen Konvertierungsfehler gab.
n := StrToIntDef(Zahl.caption, -99);
Als Anfänger (später eher nicht, aber als Anfänger finde ich das noch ok) könntest du den Tag von Label für die Zählung missbrauchen. Die Eigenschaft Tag hat keine sonstige Bedeutung, d. h. man kann damit machen was man will. Du könntest es zum zählen nutzen.
Delphi-Quellcode:
procedure TFrage2.SpeedButton4Click(Sender: TObject);
begin Zahl.Tag := Zahl.Tag + 1; Zahl.caption := IntToStr(Zahl.Tag); |
AW: Label aus anderer Unit verwenden
Zitat:
Delphi-Quellcode:
If TryStrToInt(Zahl.Caption, n) then
//String konnte konvertiert werden n := n + 1; // oder inc(n) |
AW: Label aus anderer Unit verwenden
Besser schon, aber der Tipp richtet sich an einen Anfänger der noch nicht alle Funktionen kennt (und kennen muss) und vor allem eine simple Möglichkeit den Fehler so schnell zu finden. Denn er nutzt ja einen Label und kein Edit. Ist die Fehlerquelle erst einmal lokalisiert, wird sie beseitigt und kommt nicht erneut vor. Somit ist eine permanente Überprüfung unnötig.
Arbeitet man mit Edit, so dass der Nutzer fehlerhafte Zahlen eingeben kann, kommt man um eine korrekte Überprüfung, wie z. B. mit deiner Funktion, nicht herum. |
AW: Label aus anderer Unit verwenden
Oder man geht davon dau, dass in dem Label immer eine "Zahl" steht und verwendet StrToInt.
Im Fehlerfall liefert das dann automatisch eine entsprechende Fehlermeldung und man sieht daß dort was nicht stimmt. Bei StrToIntDef würde der Fehler ungehört einfach untergehen ... das ist dann wie ein
Delphi-Quellcode:
:stupid:
try ... except {nix} end;
|
AW: Label aus anderer Unit verwenden
Danke erstmal für eure Antworten!
Habs mal soweit abgeändert, jedoch häng ich immer noch am selben Problem wie vorhin, siehe ![]() (Und ja, ihr seht schon, dass ich >9000 Units hab, aber wills für den Anfang erstmal so probieren.) |
AW: Label aus anderer Unit verwenden
himitsu, ich kann dir nicht widersprechen, denn wie kann man etwas widersprechen was eigentlich richtig ist. Aber die Frage die sich hier stellt ist nun mal - muss ein Anfänger alles wissen? Muss er try except kennen, muss er mit dem Debugger umgehen können, muss er wissen wie man in der Regel die Fehler findet, oder kann er sich behelfsmäßig helfen?
Du bist doch ein Erfahrener Programmierer, oder? Wie viele Funktionen kennst du die bei Fehler (wobei ein fehlender Wert auch eine Art Fehler ist) einen negativen Result liefern, z. B. -1. Oder ShellExecute. Alles unter 32 als Result ist Fehler. Es ist also nichts ungewöhnliches eine Zahl einen Fehler darstellt. Und was StrToIntDef angeht, die Funktion ist für dieses Beispiel schon ok, denn es erlaubt z. B. die Captions am Anfang auf "" zu löschen. Bei der ersten Operation wird aus dem leeren String dann eine Null. Der Sinn ist also da. |
AW: Label aus anderer Unit verwenden
Dein
Delphi-Quellcode:
heißt in Wirklichkeit
Richtig1.Show;
Delphi-Quellcode:
. (Delphi macht das Self innerhalb von Methoden automatisch implizit davor)
Self.Richtig1.Show;
Also, du gehst da über die Instanz des Fensters auf die Komponenten, welche darin liegen, bzw. eigentlich auf die Felder (Variablen), welche publisched in der Klasse deklariert sind. Will man auf eine andere Form, dann braucht man eine Variable, in welcher die Instanz zu dieser Form abgelegt ist und kann daber dann auch auf deren Eigenschaften zugreifen. Zitat:
und (B) solltest du gerade dann deine Units, Klassen, Variablen und vorallem Komponenten aussagefähig benennen damit man schon am Namen erkennt um was es sich handelt. |
AW: Label aus anderer Unit verwenden
@Fractal
Also der Code ist jetzt richtig, womit wir zu dem kommen was evtl. Sir Rufo meinte: was ist seine Intention (oder so in der Art)? Oder anders gefragt - hat die Funktion Zugriff auf Label Zahl? Laut Bild ist es die "Unit3", und das Fenster hat den Namen "Ergebnisse", Klasse "TErgebnisse". Die Prozedur mit der Rechnung ist in der Klasse "TFrage1". Daraus folgt - das Label "Zahl" ist auf dem Formular "Ergebnisse" und wird aus "TFrage1.SpeedButton2Click" aufgerufen. Ich weiß zwar nicht wie das intern aussieht, aber "Ergebnisse.Zahl.Caption := ..." könnte die Lösung sein. |
AW: Label aus anderer Unit verwenden
Zitat:
(Um den Counter wieder auf 0 zu setzen):
Code:
procedure TErgebnisse.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin n := StrToIntDef(Ergebnisse.Zahl.caption, 0); n := 0; Ergebnisse.Zahl.caption := IntToStr(n); end; |
AW: Label aus anderer Unit verwenden
Delphi-Quellcode:
Würde auch gehen.
procedure TErgebnisse.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin Ergebnisse.Zahl.caption := IntToStr(0); end;
Delphi-Quellcode:
Auch.
procedure TErgebnisse.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin Ergebnisse.Zahl.caption := '0'; end;
Delphi-Quellcode:
Würde aber auch gehen, wegen
procedure TErgebnisse.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin Ergebnisse.Zahl.caption := ''; end;
Delphi-Quellcode:
StrToIntDef(n, 0);
|
AW: Label aus anderer Unit verwenden
oder
Delphi-Quellcode:
Der Compiler hat aber bestimmt auch erwähnt, daß
procedure TErgebnisse.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin //n := StrToIntDef(Ergebnisse.Zahl.caption, 0); n := 0; Ergebnisse.Zahl.caption := IntToStr(n); end;
Delphi-Quellcode:
nicht verwendet wurde. (der Wert der ersten Zuweisung)
n
Vorallem, wozu sollte der alte Wert erst ausgelesen werden, wenn dann sowieso ein neuer/anderer Wert zugewiesen wird? ABER, WO um Himmels Willen ist
Delphi-Quellcode:
deklariert? :shock:
n
|
AW: Label aus anderer Unit verwenden
Ich würde das sowieso etwas anders angehen:
Merke dir eine Grundregel: Visuelle Controls dienen nur zur Anzeige, nicht zum Speichern von Daten. In deinem Fall wird die aktuelle Anzahll der richtigen Antworten aber nur als Caption im Label Zahl gespeichert. Überlege dir eine geeignete Datenstruktur für dein Quiz z.B.
Delphi-Quellcode:
Dieser Record muss natürlich beim Programmstart oder vor einem neuen Spiel sinnvoll initialisiert werden.
var
QuizErgebnisse = record //.. ganz viele nützliche Felder AnzahlRichtig : integer; end; Dein Form TErgebnisse erweiterst du um eine Methode, die die Anzahl derRichtigen Fragen entgegennimmt und irgendwie darstellt. Dabei kannst du dir auch die vielen einzelnen übereinanderliegenden Labels sparen:
Delphi-Quellcode:
procedure TErgebnisse.ShowErgebnis(AnzahlRichtig:integer);
begin Label.Caption:='Du hast '+IntToStr(AnzahlRichtig)+' / 10 Fragen richtig beantwortet!'; end; In TFrage steht dann nur:
Delphi-Quellcode:
TFrage1 muss jetzt gar nicht wissen, wie TErgebnisse das Ergebnis anzeigt. Wenn du dafür später mal ein ganz anderes Control als ein Label nehmen wilst, brauchst du nur TErgebnisse.ShowErgebnis zu ändern.
procedure TFrage1.SpeedButton2Click(Sender : TObject);
begin inc(QuizErgebnisse.AnzahlRichtig); Ergebnisse.ShowErgebnis(QuizErgebnisse.AnzahlRichtig); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:02 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-2025 by Thomas Breitkreuz