Timer funktioniert nicht

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
l0lhaxx
Beiträge: 89
Registriert: Di 8. Dez 2015, 09:20

Timer funktioniert nicht

Beitrag von l0lhaxx »

Hallo zusammen,

nachdem mir der Ratschlag erteilt wurde mit einem "einfachen" Projekt den einstieg in Lazarus zu wagen, wollte ich mir ein kleines Timer Programm schreiben.

Der Timer soll mit zwei Buttons entweder von 24h auf 0 zählen oder mit dem zweiten Button bei 20min beginnen.
Allerdings Funktioniert die Prozedure "ontimer" nicht und ich komm einfach nicht drauf wieso....
Das Programm wird zwar durch den Kompiler gejagd, sobald ich aber einen Start Button drücke wird die Zeile

procedure TForm1.Timer1Timer(Sender: TObject);

rot unterlegt und keine Funktion durchgeführt.

Wenn jemand mal drüber schauen könnte wäre ich sehr Dankbar!!!

Gruß

Code: Alles auswählen

 
unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  StdCtrls;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    btnStart1: TButton;
    btnStart2: TButton;
    btnStop: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Timer1: TTimer;
    procedure btnStart1Click(Sender: TObject);
    procedure btnStart2Click(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
 
 
 
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
  counter:Longword;
 
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
 
 
procedure TForm1.btnStart1Click(Sender: TObject);
begin
 Timer1.Enabled:=False;                                 //Falls der Timer noch aktiv ist wird er abgeschaltet
 Counter:= 1200;                                        //1200 Sekunden entspricht 20min
 Timer1.Interval:=1000;                                 //Interval 1x zählen in 1000ms (1Sekunde)
 Timer1.Enabled:=True;                                  //Timer starten
 
end;
 
procedure TForm1.btnStart2Click(Sender: TObject);
begin
 Timer1.Enabled:=False;                                //Falls der Timer noch aktiv ist wird er abgeschaltet
 Counter:= 86400;                                      //86400 Sekunden entspricht 24h
 Timer1.Interval:=1000;                                //Interval 1x zählen in 1000ms (1Sekunde)
 Timer1.Enabled:=True;                                 //Timer starten
 
end;
 
procedure TForm1.btnStopClick(Sender: TObject);
begin
 Timer1.Enabled:=False;
 counter := 86400;
 Label3.Caption:='00';
 Label2.Caption:='00';
 Label1.Caption:='00';
 
end;
 
 
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
 Timer1.Enabled:=False;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
 Timer1.Enabled:=False;
 counter := 86400;
 Label3.Caption:='00';
 Label2.Caption:='00';
 Label1.Caption:='00';
end;
 
 
procedure TForm1.Timer1Timer(Sender: TObject);
var
  SS,MM,HH:String;
  intSS, intMM, intHH:Integer ;
begin
  //Integer-Variable Counter um 1 herunterzählen
  dec(Counter);
  //Stunden, Minuten und Sekunden für die Anzeige berechnen
  intHH:=Trunc(Counter/60/60);
  intMM:=Trunc((Counter-intHH*60*60)/60);
  intSS:=Trunc(Counter- intMM*60 -intHH*60*60);
 
  SS:=IntToStr(intSS);
  MM:=IntToStr(intMM);
  HH:=IntToStr(intHH);
 //Aus optischen Gründen wird hier bei Bedarf eine "0"
 //vor die Zeitangabe gesetzt
 If Length(SS)=1 Then SS:='0' + SS ;
 If Length(MM)=1 Then MM:='0' + MM ;
 If Length(HH)=1 Then HH:='0' + HH ;
 
 //Hier wird den Labels die Beschriftung zugewiesen
 Label3.Caption:=SS;
 Label2.Caption:=MM;
 Label1.Caption:=HH;
 
 //Wenn der Counter auf "0" steht, ist die Zeit abgelaufen
 //Der Timer wird abgeschaltet und der OnStopTimer-Event ausgelöst
 If Counter=0 Then
 begin
  Timer1.Enabled:=False;
 end;
 end;
end.
 
 
 
 

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: Timer funktioniert nicht

Beitrag von theo »

Könntest du jeweils das ganze Projekt hochladen (d.h. auch lpr und lfm Dateien), wenn du gar keinen Plan hast, wo das Problem liegt?

l0lhaxx
Beiträge: 89
Registriert: Di 8. Dez 2015, 09:20

Re: Timer funktioniert nicht

Beitrag von l0lhaxx »

im Anhang.

Danke schon mal
Dateianhänge
unit1.lfm
(1.23 KiB) 47-mal heruntergeladen
project1.lpr
(382 Bytes) 32-mal heruntergeladen

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: Timer funktioniert nicht

Beitrag von theo »

Nächstes Mal bitte ein Zip mit allem drin.

Das läuft einwandfrei.
Hast du bei dir etwa einen Debugger Breakpoint gesetzt?
Ein roter Punkt in der linken Leiste des Editors?

l0lhaxx
Beiträge: 89
Registriert: Di 8. Dez 2015, 09:20

Re: Timer funktioniert nicht

Beitrag von l0lhaxx »

theo hat geschrieben:Nächstes Mal bitte ein Zip mit allem drin.

Das läuft einwandfrei.
Hast du bei dir etwa einen Debugger Breakpoint gesetzt?
Ein roter Punkt in der linken Leiste des Editors?
Nächstes mal auf jeden Fall, sorry!
Anscheinend war es wirklich der Fehler :cry: , allerdings funktioniert mein Button für 24 Stunden nicht. Dann läuft trotzdem die Zeit von 20min runter obwohl ich doch eingetlich den Counter auf 86400 setze :?:

Gibt es jetzt eigentlich eine einfache Möglichkeit das ganze quasi 5 mal zu kopieren. Also das ich fünf unterschiedliche Timer gleichzeitig starten kann ohne das jetzt nochmals alles zu schreiben?

Danke für deine Hilfe!

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: Timer funktioniert nicht

Beitrag von theo »

Dem zweiten Button hast du ja auch den Event Handler vom ersten Button zugewiesen.
Der tut so das gleiche wie Button1.

Mathias
Beiträge: 6918
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Timer funktioniert nicht

Beitrag von Mathias »

Code: Alles auswählen

 SS:=IntToStr(intSS);
  MM:=IntToStr(intMM);
  HH:=IntToStr(intHH);
 //Aus optischen Gründen wird hier bei Bedarf eine "0"
 //vor die Zeitangabe gesetzt
 If Length(SS)=1 Then SS:='0' + SS ;
 If Length(MM)=1 Then MM:='0' + MM ;
 If Length(HH)=1 Then HH:='0' + HH ;
 
 //Hier wird den Labels die Beschriftung zugewiesen
 Label3.Caption:=SS;
 Label2.Caption:=MM;
 Label1.Caption:=HH;
Hier noch ein kleiner Tip, so kannst noch ein paar Zeilen sparen.

Code: Alles auswählen

Label3.Caption:=Format('%.2d', [intSS]);
Label2.Caption:=Format('%.2d', [intMM]);
Label1.Caption:=Format('%.2d', [intHH]);
Evt. sogar nur eine Zeile:

Code: Alles auswählen

Format('%.2d:%.2d:%.2d', [intHH, intMM, intSS]);
Zuletzt geändert von Mathias am Di 12. Jan 2016, 17:11, insgesamt 1-mal geändert.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6918
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Timer funktioniert nicht

Beitrag von Mathias »

Code: Alles auswählen

  intHH:=Trunc(Counter/60/60);
  intMM:=Trunc((Counter-intHH*60*60)/60);
  intSS:=Trunc(Counter- intMM*60 -intHH*60*60);
Dies geht auch einfacher, der Umweg über eine Fliesskommazahl kannst dir sparen.

Code: Alles auswählen

Format('%.2d:%.2d:%.2d', [Counter div 3600, Counter div 60 mod 60, Counter mod 60]);
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 5153
Registriert: Fr 8. Apr 2011, 09:01

Re: Timer funktioniert nicht

Beitrag von wp_xyz »

Oder, da Counter Sekunden sind, hat man nach Division durch (24*60*60) die Einheit von TDateTime. Daher geht auch:

Code: Alles auswählen

 
  Label1 := FormatDateTime('hh:nn:ss', Counter/(24*60*60));

Mathias
Beiträge: 6918
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Timer funktioniert nicht

Beitrag von Mathias »

Wen mit : getrennt wird, kannst du es noch einfacher haben.

Code: Alles auswählen

Caption := TimeToStr(Counter / (24 * 60 * 60));
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

l0lhaxx
Beiträge: 89
Registriert: Di 8. Dez 2015, 09:20

Re: Timer funktioniert nicht

Beitrag von l0lhaxx »

Top!
Vielen Dank dafür!

Habt ihr ne Ahnung wie ich die Buttons mit denen ich gerade den Timer starte und stoppe auf ein zweites Formular "verschieben" kann?

Quasi möchte ich später zwei Formulare. Auf dem einen sollen die Labels sein und auf dem zweiten nur die Buttons.
Wie setzte ich das am besten um?

Ich habs bereits so probiert....Funktioniert aber nicht.

Code: Alles auswählen

 
unit Unit2;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Unit1;
 
type
 
  { TForm2 }
 
  TForm2 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form2: TForm2;
 
implementation
 
{$R *.lfm}
{ TForm2 }
 
procedure TForm2.Button1Click(Sender: TObject);
begin
  TForm1.Timer1.Enabled:=False;
  TForm1.Counter1:= 1200;
  TForm1.Timer1.Interval:=1000;
  TForm1.Timer1.Enabled:=True;
end;
 
end.  
 
Ein Link reicht mir schon unter Umständen.
Vielen Dank vorab!

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: Timer funktioniert nicht

Beitrag von theo »

Du musst die Instanz ansprechen, nicht die Klasse. Form1 nicht TForm1.

Form1.Timer1.Enabled:=False;

l0lhaxx
Beiträge: 89
Registriert: Di 8. Dez 2015, 09:20

Re: Timer funktioniert nicht

Beitrag von l0lhaxx »

theo hat geschrieben:Du musst die Instanz ansprechen, nicht die Klasse. Form1 nicht TForm1.

Form1.Timer1.Enabled:=False;
Super das funktioniert!

Allerdings bekomme ich mit der Variablen "counter" das Problem das er Sie wohl nicht zuordnen kann.
Gibt es eine Möglichkeit die vorhandenen Prozeduren auf der Unit1 einfach per Button der Unit2 zu starten?

So auf die Art (geschrieben in unit1):

Code: Alles auswählen

 
procedure TForm2.btnStart1Click(Sender: TObject);
begin
Timer4.Enabled:=False;                                  //Oder vielleicht auch Form1.Timer4.Enable:=False;
Counter4:= 86400;
Timer4.Interval:=1000;
Timer4.Enabled:=True;
Label4.Caption:='   XYZ   ';
end;                 
 

Antworten