![]() |
Timer und Laufzeit
Wenn zur Laufzeit einer oder mehrere Timer erstellt werden,
wie verfährt man dann mit den zugehörigen OnTimer Ereignis? Jeder Timer hat ja normalerweise sein eigenes Ereignis, wie nun wenn doch dieser erst erstellt wird? Muss man eine proc oder function für alle Timer zuweisen? Irgenwie fehlt mir der Draht... |
Re: Timer und Laufzeit
Du musst schon vorher die Methode schreiben, die vom Timer aufgerufen werden soll. Dann kannst du es wie folgt machen:
Delphi-Quellcode:
TForm1 = class(TForm)
private procedure MyTimerMethodA(Sender: TObject); procedure MyTimerMethodB(Sender: TObject); end; { ... } procedure TForm1.MyTimerMethodA(Sender: TObject); begin // // hier dein Code // // Vielleicht noch ein Umbiegen der Methode, die beim // Feuern des Timers aufgerufen werden soll ;) TTimer(Sender).OnTimer := MyTimerMethodB; end; procedure TForm1.MyTimerMethodB(Sender: TObject); begin // // hier dein Code // end; { ... } var newTimer : TTimer; begin newTimer := TTimer.Create(nil); newTimer.Enabled := False; newTimer.Interval := 1000; newTimer.OnTimer := MyTimerMethod; // hier die Zuweisung der passenden Methode newTimer.Enabled := True; end; |
Re: Timer und Laufzeit
Ok, Danke.
Also reicht eine publike proc für alle Timer?! Denn nicht alle Timer arbeiten ja gleichzeitig. Insgesamt soll will ich sowas für unseren Club machen. Sowas wie Schachuhren, zu jeden Timer gibts 1 Label (Zeit),1 Label (Punkte) und einen Button (Start/Stop). Da die Anzahl variabel ist, erzeuge ich halt erst dann alle Kompos, statt ne feste Menge. Im Ontimer wird halt dann für jeden Timer die abgelaufene Zeit usw. ermittelt und angezeigt. |
Re: Timer und Laufzeit
Für viele Schachuhren braucht man eigentlich nur einen Timer.
Dieser Timer ist nur dafür zuständig alle 0,2s die Anzeige sämlicher Schachuhren zu aktualisieren. Eine einzelne Schachuhr könnte z.B. so aussehen:
Delphi-Quellcode:
Zu Beginn ist SummeZeit = 0. Wird die Uhr gestartet, dann wird die aktuelle Uhrzeit+Datum (Funktion Now benützen) im Feld FLastStart gespeichert.
TChessClock = class(TObject)
private FLastStart : TDateTime; FSummeZeit : TDateTime; // 1.0 entspricht einem Tag, 0.04166= eine Stunde FRunning : Boolean; public procedure Start; procedure Stop; procedure Reset; function GetSummezeit:TDateTime; // liefert die aufgelaufene Zeit function GetSummeZeitAsString:string; property Running : Boolean read FRunning; end; ... function TChessClock.GetSummezeit:TDateTime; begin if Running then result := FSummeZeit + (Now-FLastStart) else result := FSummeZeit; end; Wird die Uhr gestoppt, dann wird intern gerechnet:
Delphi-Quellcode:
Man kann die Uhr auch so designen, dass mit einer Zeitvorgabe (z.B. 10Min) gestartet wird und dann dieses Zeitguthaben verkleinert wird.
FSummeZeit := FSummeZeit + (Now - FLastStart);
Für ein Schachspiel müssen zwei Uhren zusammengenommen werden. Hier würde ich eine weitere Klasse verwenden, um zwei Objekte von TChessClock zusammenzufassen. Beim Stop der einen Uhr startet wird automatisch die Uhr des Gegners gestartet. Dann kann man beliebig viele Objekte dieser Doppeluhren in einer TObjectList oder in einem dyn. Array anlegen. Der Timer hat dann "nur" noch die Aufgabe, alle Doppeluhren aus der Liste auszulesen und im Formular anzuzeigen. |
Re: Timer und Laufzeit
Danke für die Tipps,
aber genau daran hängt es. Zitat:
Ich habe jedem Label (Zeit) einen eindeutigen Tag zugwiesen, soll die die Tags in ein Array stopfen, oder die Labels in eine Objektliste? :( |
Re: Timer und Laufzeit
Zitat:
Aber ich würde hier zu "höherwertigen" Datenstrukturen wie Objektlisten greifen und (dynamische) Arrays mehr "in der Tiefe", also verborgen in Klassen, verwenden. Aber Dir fehlt im Grunde genommen noch eine Klasse. Diese Klasse dient als Adapter zwischen der Doppeluhr und den Controls der Benutzeroberfläche. Es sieht erstmal nach mehr Arbeit aus, aber dafür vereinfacht sich der Code im Formular. Hier mal ganz grob diese Klasse:
Delphi-Quellcode:
Das mit dem Status-Label kann man natürlich auch schöner machen; z.B. Namen des Spielers anzeigen und zusätzlich mit zwei Icons anzeigen, welcher Spieler am Zug ist.
TGameClockAdapter=class(TObject)
public GameClock : TGameClock; // die Doppeluhr LabelPlayerA : TLabel; // Zeitanzeige Spieler A LabelPlayerB : TLabel; // Zeitanzeige Spieler B LabelStatus : TLabel; // Anzeige, welcher Spieler am Zug ist destructor Destroy;override; procedure RefreshUserInterface; procedure StartNewGame; procedure PauseGame; ... end; ... procedure TGameClockAdapter.RefreshUserInterface; begin LabelPlayerA.Caption := GameClock.PlayerA.GetSummeZeitAsString; LabelPlayerB.Caption := GameClock.PlayerB.GetSummeZeitAsString; if GameClock.PlayerA.Running then LabelStatus.Caption := 'Spieler A am Zug' else LabelStatus.Caption := 'Spieler B am Zug' end; destructor TGameClockAdapter.Destroy; begin GameClock.Free; inherited; end; Der Ablauf sieht so aus: Objekte von TGameClockAdapter erzeugen, jeweils ein GameClock-Objekt erzeugen und dem TGameClockAdapter-Objekt mitgeben. Dann die 3 Labels zuweisen. Diese TGameClockAdapter Objekte werden nun in einer Objektliste gespeichert. Und dann noch der Eventhandler für den Timer:
Delphi-Quellcode:
procedure TForm1.TimerAllTimer(Sender:TObject)
var i : integer; begin // Azeige für alle Doppeluhren aktualisieren for i := 0 to FGameClockList.Count-1 do begin (FGameClockList.Objects[i] as TGameClockAdapter).RefreshUserInterface; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:23 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