Sleep Funktion richtig nutzen?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
bluebee
Beiträge: 1
Registriert: Mo 11. Mai 2020, 18:04

Sleep Funktion richtig nutzen?

Beitrag von bluebee »

Ich habe eine Frage bezüglich der Sleep Funktion. Ich soll eine Ampel zeichnen und dann die verschiedenen Lichter für bestimmte Zeitenaufleuchten lassen und diesen Prozess 5 Mal durchlaufen lassen. Eigentlich habe ich genau das getan, was vorgegeben wurde, aber sobald ich den Knopf zum Starten drücke, passiert erstmal gar nichts bis irgendwann nur das Bild auftaucht.
Hier ist der Code (ohne, wie die Ampel gezeichnet wird).

Code: Alles auswählen

for i:=1 to 5 do begin
      brush.color:=clred;
      ellipse(225,65,275,115);
      sleep(15000);
      brush.color:=clblack;
      ellipse(225,65,275,115);

      brush.color:=clyellow;
      ellipse(225,125,275,175);
      sleep(4000);
      brush.color:=clblack;
      ellipse(225,125,275,175);

      brush.color:=clgreen;
      ellipse(225,185,275,235);
      sleep(8000);
      brush.color:=clblack;
      ellipse(225,185,275,235);
    end; 
    

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

Re: Sleep Funktion richtig nutzen?

Beitrag von Mathias »

Du blockierst dein ganzes Programm mit Sleep, somit kann auch nichts gezeichnet werden.
Ich würde die Ampel über einen Timer steuern.
Mit dem Timer würde ich dann nur Flag setzen.
Gezeichnet wird dann in onPaint.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 4182
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: Sleep Funktion richtig nutzen?

Beitrag von af0815 »

Grundlegend wird nur gezeichnet wenn die entsprechenden Routinen über das Botschaftssystem abgearbeitet werden. Das ist bei der Linearen Programmierung mit zusätzlichen sleeps erst der Fall, wenn die Procedur oder Funktion abgearbeitet ist. Da hilft dier, so wie Mathias geschrieben hat, es wenig, das du Verzögerungen mit sleeps machst.

Eine gewisse Krücke ist, wenn du nach dem Sleeps ein Application.ProcessMessages machst. Wird vermutlich für eine Hausübung zur Not reichen, wenn keine besonderen Sachen verlangt werden. Damit wird ein bearbeiten der Botschaftsschlange ermöglicht. Zeigt oft aber nicht vom umwerfenden Design.

BTW: Es gibt Betriebsystemvarianten (angebissenes Obst), wo du nur im OnPaint zeichnen kannst. da hilft dir ein Application.Processmessages nichts.


Konklusio: Für deinen Zweck ist die Sleepfunktion nicht richtig zu nutzen :-)
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

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

Re: Sleep Funktion richtig nutzen?

Beitrag von Mathias »

Was noch eine billige Lösung ist, eine Konsolenanwendung zu schreiben.
Uses Crt einbinden, dann kann man die Audgabe beliebig einfärben, und den Cursor positionieren.

Nochmal zu oben zurück. Wen man auf onPaint verzichten will, ein TShape nehmen, und diese im Timer umfärben.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

mschnell
Beiträge: 3412
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Sleep Funktion richtig nutzen?

Beitrag von mschnell »

Sleep im Mainthread einer GUI - Anwendung ist verboten.
-Michael

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

Re: Sleep Funktion richtig nutzen?

Beitrag von Mathias »

Es gibt kleine Ausnahmen, das man vielleicht mal ein Sleep(10) braucht, wen man Timing-Probleme bei einer Schnittstelle hat.
Aber sicher kein Sleep(1000) oder gar höher,
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 4182
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: Sleep Funktion richtig nutzen?

Beitrag von af0815 »

mschnell hat geschrieben:
Di 12. Mai 2020, 12:45
Sleep im Mainthread einer GUI - Anwendung ist verboten.
Nicht zwingend, mit sleep(0) kann man ruhig einen Wechsel des aktiven Threads veranlassen. 8)

Wenn man sleep oder Application.Processmessages verwendet, sollte man sich über die versteckten Funktionen des LCL und der Widgetsets im klaren sein. Auch wie die Messages im System verwendet werden.

Timer und StateMachines sind fast immer die bessere Wahl.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Winni
Beiträge: 271
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.06, fpc 3.04
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Sleep Funktion richtig nutzen?

Beitrag von Winni »

Hallo!

Wie erwähnt sollte sleep nicht im MainThread verwendet werden.

Als Lösung gibt es - neben dem Timer - noch die Möglichkeit, die zeitabhängigen Funktionen in einen Thread auszulagern.

Wenn man sleep unbedingt im MainThread benutzen will, muss man sich das ,selbst schreiben:

Code: Alles auswählen

procedure sleeep (ms: Integer); inline;
var start: QWord;
begin
  start := GetTickCount64;
  repeat
    application.ProcessMessages;
     until GetTickCount64 - start >= ms;
end;                   

Das funktioniert, ist aber unschön.

Gerade bei einer Ampel bietet sich ein Timer an.

Winni

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 598
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.7 FPC 3.04)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Sleep Funktion richtig nutzen?

Beitrag von fliegermichl »

Ich konnte mich dunkel daran erinnern, daß wir das Thema vor langem schonmal hatten.
Da habe ich ein funktionierendes Beispiel mit Timer und Shapes hochgeladen.

Ist hier zu finden
Den Thread, in dem das besprochen wurde, findest du hier

Antworten