Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Timerabruf (Timer2) bei Timerablauf (Timer1) (https://www.delphipraxis.net/92425-timerabruf-timer2-bei-timerablauf-timer1.html)

Svenkan 19. Mai 2007 15:47


Timerabruf (Timer2) bei Timerablauf (Timer1)
 
Ich möchte Timer2 aufrufen, sobald Timer1 abgelaufen ist. Wenn ich dies über
Delphi-Quellcode:
if TimerReload.Interval<=1 then TimerNextTab.OnTimer(TimerNextTab);
mache, wird dieser aber trotzdem nie abgerufen.

Jürgen Thomas 19. Mai 2007 16:05

Re: Timerabruf (Timer2) bei Timerablauf (Timer1)
 
Hallo,

ich verstehe nicht ganz, was Du willst (vor allem wenn ich Deine Konstruktion und Bezeichner lese). Nach Deiner Fragestellung würde ich einfach Folgendes machen:
Delphi-Quellcode:
procedure MyForm.Timer1OnTimer(Sender: TObject);
begin
  Timer1.Enabled := false;
  Timer2.Enabled := true;
end;
Oder was verstehe ich falsch? Jürgen

Svenkan 19. Mai 2007 16:07

Re: Timerabruf (Timer2) bei Timerablauf (Timer1)
 
Also ich habe ein Programm, womit ich den aktuellen Vertretungsplan aus einer dbf abrufen und auf dem Monitor anzeigen lasse.
Nun kann man einstellen, wie lange eine Seite eingeblendet sein soll.
Wenn diese Zeit abgelaufen ist, soll TimerNextTab abgerufen werden, damit der jeweilige Wechsel vorgenommen werden kann.
Das Problem ist nur, dass er wenn er auf die letzte Seite wechselt und gleichzeitig der Timer aktiviert wird, er direkt auf den nächsten Tag wechselt.

Jürgen Thomas 19. Mai 2007 16:22

Re: Timerabruf (Timer2) bei Timerablauf (Timer1)
 
Aaaahhh! Du willst keinen zweiten Timer aktivieren, sondern einen Timer ein weiteres Mal (ggf. mit anderen Werten) aufrufen. Dann hast Du zwei Sachen nicht verstanden, wie ein Timer arbeitet:
  • Der Timer wird nicht "immer wieder" aufgerufen, bis er abgelaufen ist, sondern einmal (bzw. jedes Mal), wenn seine Gültigkeit endet.
  • Solange Timer.Enabled = true gilt, wird er erneut aktiviert.
  • Das Interval gibt an, nach welcher Zeit er abgelaufen ist.
  • Mögliche Maßnahmen (bei Dir das Umschalten) werden genau zu diesem Zeitpunkt ausgeführt.
Deine if-Abfrage wäre also nur dann wahr, wenn das Interval auf 0/1 gesetzt würde.

Du musst also nach folgendem Schema vorgehen:
Delphi-Quellcode:
private NextTabTimer: TTimer;
//  Startwert auf 5 Sekunden einstellen
NextTabTimer.Interval := 5000;
//  Timer aktivieren, nachdem z.B. Daten eingelesen wurden
NextTabTimer.Enabled := true;
Anzeige.TabIndex := 0;
//  umschalten nach 5 Sekunden
//  weitere Seiten werden 10 Sekunden angezeigt
procedure MyForm.NextTabTimerOnTimer(Sender: TObject);
begin
  NextTabTimer.Interval := 10000;
  //  nach der letzten Tab-Seite deaktivieren, sonst weiterschalten
  if Anzeige.TabIndex = 4
  then NextTabTimer.Enabled := false
  else Anzeige.TabIndex := Anzeige.TabIndex + 1;
end;
Viel Erfolg! Jürgen

Svenkan 19. Mai 2007 16:32

Re: Timerabruf (Timer2) bei Timerablauf (Timer1)
 
Also, am besten, ich erklär alles nochmal ganz genau. :D

Also:
AktuSeiten (TabIndex1) bzw. AktuSeitena (TabIndex2) = aktuelle Seiten
TimerReload = holt regelmäßig die Vertretungsdaten
TimerNextTab = Umschalten des TabIndexes

Wenn nun AktuSeite bzw. AktuSeitea = 0 und TimerReload abgelaufen ist (nicht vor dem Umschalten auf AktuSeite = 0, sondern erst, nachdem diese letzte Seite x Sekunden [sprich die Zeit aus dem Timer] angezeigt worden ist!), soll TimerNextTab abgerufen werden.
In diesem soll dann halt das Umschalten geregelt werden (TabIndex0 ---> 1; 1 ---> 2; 2 ---> 0).

Jürgen Thomas 19. Mai 2007 16:47

Re: Timerabruf (Timer2) bei Timerablauf (Timer1)
 
Also doch, wie ich es schon in meiner ersten Antwort gesagt habe: die beiden Timer aktivieren und deaktivieren sich gegenseitig.
Delphi-Quellcode:
//  vereinfacht: die Intervalle bleiben konstant
TimerReload.Interval = 30000;
TimerNextTab.Interval = 10000;

//  Anzeige weiterschalten:
procedure MyForm.TimerNextTabOnTimer(Sender: TObject);
begin
  if Anzeige.TabIndex = 2
  then begin
    Anzeige.TabIndex := 0;
    //  das Weiterschalten deaktivieren, damit erst einmal eingelesen werden kann
    TimerNextTab.Enabled := false;
  end
  else begin
    Anzeige.TabIndex := Anzeige.TabIndex + 1;
  end;
end;

//  Daten neu einlesen
procedure MyForm.TimerReloadOnTimer(Sender: TObject);
begin
  if Anzeige.TabIndex = 0
  then begin
    DatenNeuEinlesen();
    //  das Weiterschalten aktivieren
    TimerNextTab.Enabled := true;
  end;
end;
Das Zusammenspiel könnte in der Praxis vereinfacht werden. Eigentlich brauchst Du den TimerReload überhaupt nicht, sondern liest die Daten einfach dann ein, wenn er wieder auf TabIndex 0 umgeschaltet hat. Aber das ist ein anderes Thema.

Gruß Jürgen

Svenkan 19. Mai 2007 16:55

Re: Timerabruf (Timer2) bei Timerablauf (Timer1)
 
Ja schon, allerdings funktioniert es so nur richtig beim TabIndex2, wo nur die Meldung angezeigt werden.
Denn wenn ein Tag nur eine Seite hat, dann wird dieser direkt übersprungen. Denn der Timer geht momentan direkt weiter, sobald er auf AktuSeite bzw AktuSeitea = 0 trifft und nicht erst, nachdem diese Seite 0 x Sek angezeigt wurde.

Jürgen Thomas 19. Mai 2007 17:09

Re: Timerabruf (Timer2) bei Timerablauf (Timer1)
 
Tut mir leid, dann bin ich nicht mehr fähig zu raten. Wie wäre es, wenn Du uns Deinen bisherigen Code angäbest?!
  • Intervall der beiden Timer
  • Einstellung, wann sie aktiviert werden
  • Code für die Timer-Ereignisse
  • wann und wo/wie die Daten eingelesen werden
Jürgen

Svenkan 19. Mai 2007 17:20

Re: Timerabruf (Timer2) bei Timerablauf (Timer1)
 
Reload-Prozedur

Delphi-Quellcode:
procedure TForm2.TimerReloadTimer(Sender: TObject);
var
   Ini: TIniFile;
   y,ya,i,ia,count,count2,counta,countb,ReloadTime,dnr:integer;
   morgen_m: String;
   tomorrow,today: TDateTime;
begin
  dnr:=DayOfWeek(Date);
  if dnr=7 then begin
   today:=Date+2;
   tomorrow:=Date+3;
  end
  else if dnr=6 then begin
   today:=Date+3;
   tomorrow:=Date+4;
  end
  else begin
   today:=Date;
   tomorrow:=Date+1;
  end;

 try
    Ini:=TIniFile.Create(ExtractFilePath(ParamStr(0))+'conf.ini');
    ReloadTime:=(Ini.ReadInteger('Zeiteinstellungen','Tagwechsel',10)*1000);
    morgen_m:=Ini.ReadString('Zeiteinstellungen','Datum morgen',DatetoStr(tomorrow));
    if StrToDate(morgen_m)<tomorrow then morgen_m:=DateToStr(tomorrow)
    else tomorrow:=StrToDate(morgen_m);
  finally
    Ini.Free;
  end;

  if PageControl1.TabIndex=0 then begin
   Label5.Caption:='Vertretungsplan für den';
   Label6.Caption:=DateToStr(today)+' (heute)';
  end
  else if PageControl1.TabIndex=1 then begin
   Label5.Caption:='Vertretungsplan für den';
   Label6.Caption:=DatetoStr(tomorrow);
  end
  else begin
   Label5.Caption:='Meldungen';
   Label6.Caption:='';
  end;

  TimerReload.Interval:=ReloadTime;

 if PageControl1.TabIndex=0 then begin

  if aktuseite = Gesseiten then
    count := length(Daten) mod 19
  else
    count := 19;
  y:= 19*AktuSeite;
  stringgrid1.RowCount:=count+1;
  for i:=0 to count-1 do begin
    stringgrid1.Cells[0,i+1]:= Daten[i+y].klasse;
    stringgrid1.Cells[1,i+1]:= Daten[i+y].stunde;
    stringgrid1.Cells[2,i+1]:= Daten[i+y].fuer;
    stringgrid1.Cells[3,i+1]:= Daten[i+y].wer;
    stringgrid1.Cells[4,i+1]:= Daten[i+y].fach;
    stringgrid1.Cells[5,i+1]:= Daten[i+y].raum;
    stringgrid1.Cells[6,i+1]:= Daten[i+y].bemerkung;
  end;

  if AktuSeite = GesSeiten then
    AktuSeite := 0
  else
    AktuSeite:=AktuSeite+1;
 end
 else if PageControl1.TabIndex=1 then begin

  if aktuseitea = Gesseitena then
    counta := length(Daten2) mod 19
  else
    counta := 19;
  ya:= 19*AktuSeitea;

  stringgrid2.RowCount:=counta+1;
  for ia:=0 to counta-1 do begin
    stringgrid2.Cells[0,ia+1]:= Daten2[ia+ya].klasse;
    stringgrid2.Cells[1,ia+1]:= Daten2[ia+ya].stunde;
    stringgrid2.Cells[3,ia+1]:= Daten2[ia+ya].fuer;
    stringgrid2.Cells[2,ia+1]:= Daten2[ia+ya].wer;
    stringgrid2.Cells[4,ia+1]:= Daten2[ia+ya].fach;
    stringgrid2.Cells[5,ia+1]:= Daten2[ia+ya].raum;
    stringgrid2.Cells[6,ia+1]:= Daten2[ia+ya].bemerkung;
  end;

  if AktuSeitea = GesSeitena then
    AktuSeitea := 0
  else
    AktuSeitea:=AktuSeitea+1;
 end;

TimerNextTab.Enabled:=True;
end;
NextTab-Timer:

Delphi-Quellcode:
procedure TForm2.TimerNextTabTimer(Sender: TObject);
var Ini: TIniFile;
    dnr,interval: Integer;
    morgen_m: String;
    tomorrow,today: TDateTime;
begin
  dnr:=DayOfWeek(Date);
  if dnr=7 then begin
   today:=Date+2;
   tomorrow:=Date+3;
  end
  else if dnr=6 then begin
   today:=Date+3;
   tomorrow:=Date+4;
  end
  else begin
   today:=Date;
   tomorrow:=Date+1;
  end;

 try
    Ini:=TIniFile.Create(ExtractFilePath(ParamStr(0))+'conf.ini');
    interval:=(Ini.ReadInteger('Zeiteinstellungen','Tagwechsel',10)*1000);
    morgen_m:=Ini.ReadString('Zeiteinstellungen','Datum morgen',DatetoStr(tomorrow));
    if StrToDate(morgen_m)<tomorrow then morgen_m:=DateToStr(tomorrow)
    else tomorrow:=StrToDate(morgen_m);
  finally
    Ini.Free;
  end;

if PageControl1.TabIndex=0 then
    begin
    PageControl1.TabIndex:=1;
    TimerNextTab.Enabled:=False;
    TimerNextTab.Interval:=interval;
    Label5.Caption:='Vertretungsplan für den';
    Label6.Caption:=DateToStr(today)+' (heute)';
    end
    else
      if PageControl1.TabIndex=1 then
        begin
          PageControl1.TabIndex:=2;
          TimerNextTab.Enabled:=False;
          TimerNextTab.Interval:=interval;
          Label5.Caption:='Vertretungsplan für den';
          Label6.Caption:=DateToStr(Tomorrow);
        end
        else
          if PageControl1.TabIndex=2 then
            begin
            PageControl1.TabIndex:=0;
            TimerNextTab.Enabled:=False;
            TimerNextTab.Interval:=interval;
            Label5.Caption:='Meldungen';
            Label6.Caption:='';
            end
end;
Der Interval wird jeweils aus einer Ini-Datei ausgelesen.

Jürgen Thomas 19. Mai 2007 18:07

Re: Timerabruf (Timer2) bei Timerablauf (Timer1)
 
Hallo Svenkan,

dringende Empfehlung: Strukturiere Deinen Code übersichtlicher:
  • Code-Teile, die sich wiederholen, werden ausgelagert (z.B. interval aus Ini einlesen; date/tomorrow bestimmen).
  • Bleibt das Interval nicht konstant während eines Programmlaufs? Wenn ja, dann gehört das nach FormOnCreate o.ä.
  • "Richtige" Abläufe gehören nicht in die Ereignisprozedur, sondern in eigene Prozeduren. (Das habe ich durch meine Prozedur DatenNeuEinlesen angedeutet.)
  • Einrückungen konsequent beachten: immer 2 Zeichen; was zusammengehört, steht übereinander (try-finally).
Nachtrag: Kommentare helfen ebenfalls sehr. Ich glaube nicht, dass Du übermorgen noch durch Deinen Code durchblickst.

Im Moment erschwerst Du mir/uns das Verständnis viel zu sehr. Du willst schließlich Hilfe; also solltest Du uns dies erleichtern.

Gruß Jürgen


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:17 Uhr.
Seite 1 von 2  1 2      

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