Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Eins nach dem anderen abarbeiten


Stread - Mi 21.04.10 19:37
Titel: Eins nach dem anderen abarbeiten
Hi,

ich habe mit einem Timer einen Countdown von 5 sek. auf 0 sek. Dieser wird mir in einem Edit Feld angezeigt wenn ich auf einen Button drücke. Nach dem Countdown soll das Programm noch anderes machen. Mein Problem ist: Wie bekomme ich es hin dass erst die 5 Sekunden ablaufen und dann das Programm fortgesetzt wird? Mit sleep geht auch der Timer nicht weiter. Brauche ich einen Timer für den Timer? :shock:


Jann1k - Mi 21.04.10 19:51

Mehrere Möglichkeiten:

1) Du überprüfst in deiner "anderen" Prozedur in einer while-Schleife, ob der Timer schon fertig mit zählen ist (mit application.processmessages kannst du verhindern, dass dein Programm während der Schleife einfriert).

2) Wenn dein Timer mit dem Zählen fertig ist startet er den "anderen" Programmabschnitt (würde ich als Lösung bevorzugen).


Was du dir überlegen musst, ist was der User während des Countdowns noch machen können soll/darf, und alles andere "abschalten".


Chemiker - Mi 21.04.10 20:08

Hallo Stread,

vielleicht so:




Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  iTicks:= 0;
  Timer1.Enabled:= TRUE;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  t: String;
  h, m, s: integer;
begin
  iTicks:= iTicks+1;
  s:= iTicks mod 60;
  m:= (iTicks div 60mod 60;
  h:= (iTicks div 3600mod 24;

  t:= Format('%2.2d:%2.2d:%2.2d', [h, m, s]);
  Edit1.Text:= t;
  Repaint;
  if iTicks= 5 then
  begin
    Timer1.Enabled:= FALSE;
  end;
end;


Bis bald Chemiker


Stread - Mi 21.04.10 20:31

Der Benutzer soll nur dem Countdown zusehen und ihn abbrechen können wenn er auf einen Button klickt.
Wann soll das application.processmessages stehen? Am Anfang? In der Schleife? Nur einmal in der ganzen Prozedur?

2) hört sich am besten an aber WIE soll ich das machen? Wie merkt er dass der Timer fertig ist und wie startet/ oder wie setzt er den Programmabschnitt fort?


Chemiker: Ist das nicht ein bisschen zu aufwändig?


Hidden - Mi 21.04.10 21:01

Hi :)

Einen Timer nehmen, und dann eine Schleife laufen lassen, bis der Timer abgelaufen ist, ist verrückt..

Lösung: Prozedur aufteilen. Der erste Teil läuft ab, startet den Timer und ist fertig. Im OnTimer-Ereignis wir dann der zweite Teil der Prozedur aufgerufen.

lg,


Stread - Mi 21.04.10 21:18

Auch wenn der 2. Teil 99% der Prozedur ausmacht?
ich hab es jetzt so gemacht:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TForm12.Button1Click(Sender: TObject);
begin
PrZeit:=5;
TimerPrStart.Enabled:=True;
while PrZeit<>0 do
begin
Application.ProcessMessages;
end;
X1:=....


GuaAck - Mi 21.04.10 21:31

Hi,

Warum nicht anfach alle anderen Arbeiten in der OnTimer-Routine machen, also im Vorschlag von Chemiker

Delphi-Quelltext
1:
2:
3:
4:
5:
IF sTick=5 then
 begin
  Timer1.enabled:=false;
  mache_vieles_andere;
 end;

Gruß
Guenther

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


Hidden - Mi 21.04.10 21:34

Hi :)

Japp, die Länge des auszuführenden Codesegments ist dabei eigentlich egal.

Also genauso, wie user profile iconGuaAck das gerade schreibt, falls ich anders verstanden wurde.

lg,


Chemiker - Mi 21.04.10 22:07

Hallo Stread,
Zitat:
Chemiker: Ist das nicht ein bisschen zu aufwändig?


Das meiste ist doch für das Darstellen in der Edit-Komponente erforderlich.
Zitat:
Der Benutzer soll nur dem Countdown zusehen und ihn abbrechen können wenn er auf einen Button klickt.

Überarbeitet Fassung:



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
procedure TForm1.btStartClick(Sender: TObject);
begin
  iTicks:= 6;
  Timer1.Enabled:= TRUE;
  btStop.Enabled:= TRUE;
  btStart.Enabled:= FALSE;
end;

procedure TForm1.btStopClick(Sender: TObject);
begin
  Timer1.Enabled:= FALSE;
  btStop.Enabled:= FALSE;
  btStart.Enabled:= TRUE;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  t: String;
  h, m, s: integer;
begin
  iTicks:= iTicks-1;
  s:= iTicks mod 60;
  m:= (iTicks div 60mod 60;
  h:= (iTicks div 3600mod 24;

  t:= Format('%2.2d:%2.2d:%2.2d', [h, m, s]);
  Edit1.Text:= t;
  Repaint;
  if iTicks= 0 then
  begin
    Timer1.Enabled:= FALSE;
  end;
end;


Bis bald Chemiker


Hidden - Mi 21.04.10 22:18

Hi :)

Statt eines Edits würde ich dann auch jeden Fall ein Label nehmen.
Der Quelltext von user profile iconChemiker lässt ja eigentlich immer noch die Frage offen, wo denn die eigentliche Prozedur aufgerufen wird(vmtl. vergessen). Die käme dann noch in die Abfrage "iTicks = 0" rein.

lg,


Chemiker - Do 22.04.10 01:31

Hallo Hidden,

und in den Stopp-Button-Ereignis.
2 Version:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
unit frmDemoTimerDemo;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Edit1: TEdit;
    btStop: TButton;
    btStart: TButton;
    btSchliessen: TButton;
    procedure Timer1Timer(Sender: TObject);
    procedure btStartClick(Sender: TObject);
    procedure btStopClick(Sender: TObject);
    procedure btSchliessenClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    iTicks: integer;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure PRG_Starten();
begin
  ShowMessage('Das Programm ist gestartet');
  Form1.btSchliessen.Enabled:= TRUE;
end;

procedure TForm1.btSchliessenClick(Sender: TObject);
begin
  close;
end;

procedure TForm1.btStartClick(Sender: TObject);
begin
  iTicks:= 6;
  Timer1.Enabled:= TRUE;
  btStop.Enabled:= TRUE;
  btStart.Enabled:= FALSE;
end;

procedure TForm1.btStopClick(Sender: TObject);
begin
  Timer1.Enabled:= FALSE;
  btStop.Enabled:= FALSE;
  btStart.Enabled:= TRUE;
  PRG_Starten();
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if not (Timer1.Enabled) then
  begin
    Action:= caFree;
  end else
  begin
    Action := caNone;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  t: String;
  h, m, s: integer;
begin
  iTicks:= iTicks-1;
  s:= iTicks mod 60;
  m:= (iTicks div 60mod 60;
  h:= (iTicks div 3600mod 24;

  t:= Format('%2.2d:%2.2d:%2.2d', [h, m, s]);
  Edit1.Text:= t;
  Repaint;
  if iTicks= 0 then
  begin
    Timer1.Enabled:= FALSE;
    PRG_Starten();
  end;
end;
end.;


Bis bals Chemiker


Hidden - Do 22.04.10 08:51

Hi :)

Der Stopp-Button dient glaube ich zum Abbrechen, oder?
Aber ein Sofort-Starten-Button wäre eventuell auch gut.

Intuitiv würde ich jetzt erwarten, dass der Countdown abgebrochen wird und das Programm geschlossen, wenn ich das Fenster schließe.

lg,