Card im Hintergrund / Timer im NumberFormat „00“

Startseite Foren Deutsches LiveCode-Forum Card im Hintergrund / Timer im NumberFormat „00“

Schlagwörter: , , ,

Ansicht von 4 Antwort-Themen
  • Autor
    Beiträge
    • #26028
      Aldred
      Teilnehmer

      Hallo ihr Lieben und einen wunderschönen Samstag!

      Heute beehre ich euch mit zwei Fragen:

      1. Card im Hintergrund laufen lassen:

      Ich habe in meinem Substack 4 Cards die ich über eine NavBar ansteuern kann. Auf Card 1 kann ich einen Timer ablaufen lassen der natürlich weiterlaufen sollte, selbst wenn ich die Cards wechsle.
      Der Timer-Handler holt sich die aktuelle TimerZeit aus dem dafür vorgesehenen Field, bearbeitet sie (+ 1 Sekunde) und schreibt die neue Timer-Zeit wieder in selbiges Feld zurück.

      Wenn ich nun die Cards wechsle, kommt die Fehlermeldung, dass es dieses Timer-Feld nicht mehr gibt. Was ich auch verstehen kann, da die Card ja nicht mehr geöffnet ist.
      Gibt es eine Möglichkeit die Card im Hintergrund offen zu lassen, so dass der Handler in Ruhe weiter „Timen“ kann?

      2. Timer im NumberFormat „00“
      Jener oben beschriebene Timer funktioniert erstmal einwandfrei.

      
      on startArbeitsTimer
         
         put the text of fld "fStdHeute" of cd "Start" into tStd
         put the text of fld "fMinHeute" of cd "Start" into tMin
         put the text of fld "fSecHeute" of cd "Start" into tSec
         put tStd &":"& tMin &":"& tSec into tZeit
         convert tZeit to seconds
         subtract 1 of tZeit
         convert tZeit to dateItems
         set the numberFormat to "00"
         put item 4 of tZeit into tStdNeu
         put item 5 of tZeit into tMinNeu
         put item 6 of tZeit into tSecNeu
         set the text of fld "fStdHeute" to tStdNeu
         set the text of fld "fMinHeute" to tMinNeu
         set the text of fld "fSecHeute" to tSecNeu
         send startArbeitsTimer to me in 1000 milliseconds
         
         if tStdNeu = 0 and tMinNeu = 0 and tSecNeu = 0 then
            set the text of fld "fStdHeute" of cd "Start" to tStdNeu
            set the text of fld "fMinHeute" of cd "Start" to tMinNeu
            set the text of fld "fSecHeute" of cd "Start" to tSecNeu
            stopArbeitsTimer
            set the visible of grp "group_US" of cd "Start" to true
            startUberstundenTimer
            
         end if
         
      end startArbeitsTimer

      Problem ist folgendes: sobald die Zahl einstellig wird, wird auch nur eine Stelle angezeigt. Trotz numberFormat „00“
      Setze ich die zusätzliche 0 per Script ein, nimmt er diese zwei Zahlen bei der nächsten Timer-Runde wieder aus dem Field und es geht nicht weiter.

      So… What to do? 🙂

      Liebe Grüße
      Aldred

    • #26033
      Klaus Major
      Verwalter

      Hi Aldred,

      1.

      Gibt es eine Möglichkeit die Card im Hintergrund offen zu lassen

      nein, gibt es natürlich nicht.
      Aber wie bei der Post (nur viel besser) kommt mit der richtigen Adresse alles korrekt beim Empfänger an!
      Schau Dir diese zwei Zeilen aus dem Skript an und finde den Unterschied:

      put the text of fld "fStdHeute" of cd "Start" into tStd
      ...
      set the text of fld "fStdHeute" to tStdNeu

      Capisce?
      Füge -> of cd „Start“
      hinzu und das wars! 🙂

      2. numberformat
      Das setzen von NUMBERFORMAT beeiinflusst nur alle nachfolgenden mathematischen Operationen.
      Diese können (und müssen) wir hier simulieren.
      Beispiel:

      set the numberformat to "00"
      put 1
      ## -> 1
      ## ABER hier der Trick:
      put 1 + 0
      ## -> 01
      ## Bescheuert, aber funktioniert! :-D

      Allerdings benötigen wir hier gar nicht NUMBERFORMAT, da LC SEHR gut mit Datum und Zeit rechnen kann!

      on startArbeitsTimer
         
         ## Wir benötigen eigentlich keine extra Variablen hierfür
         put the text of fld "fStdHeute" of cd "Start" & ":" & the text of fld "fMinHeute" of cd "Start" & ":" & the text of fld "fSecHeute" of cd "Start" into tSec
         
         ## LC denkt englisch, also ist 14:00 Uhr für LC 
         ## -> 2:00 PM
         ## Das wollen wir nicht, daher:
         set the twelvehourtime to FALSE
         convert tZeit to seconds
         subtract 1 of tZeit
         
         ## Hier der Trick OHNE numberformat:
         convert tZeit to LONG TIME
         ## Das ergibt die neue Zeit im gewünschten Format!
         ## -> 13:07:11
         ## dateitems wären etwas OVERKILL in diesem Fall
            
         set itemdel to ":"
         set the text of fld "fStdHeute" OF CD "Start" to item 1 of tZeit
         set the text of fld "fMinHeute" OF CD "Start" to item 2 of tZeit
         set the text of fld "fSecHeute" OF CD "Start" to item 3 of tZeit   
         ## Das deckt ja auch 0 ab, was Du aber explizit im IF Fall noch einmal gemacht hast.
         
         ## Ge-SEND-ete Messages immer in Anführungszeichen!
         send "startArbeitsTimer" to me in 1000 milliseconds
         
         if tZeit = "00:00:00" then
            stopArbeitsTimer
            set the visible of grp "group_US" of cd "Start" to true
            startUberstundenTimer
         end if   
      end startArbeitsTimer

      Gruß

      Klaus

    • #26034
      Klaus Major
      Verwalter

      Bin mir allerdings nicht sicher, ob es so richtig(er) wäre:

         set the text of fld "fSecHeute" OF CD "Start" to item 3 of tZeit   
         ## Das deckt ja auch 0 ab, was Du aber explizit im IF Fall noch einmal gemacht hast. 
         
         if tZeit = "00:00:00" then
            stopArbeitsTimer
            set the visible of grp "group_US" of cd "Start" to true
            startUberstundenTimer
      
            ## Der "ArbeitsTimer" hat ja jetzt seine Schuldigkeit getan, oder?
            ## Daher packen wir das in einen ELSE Fall
          else
           ## Ge-SEND-ete Messages immer in Anführungszeichen!
           send "startArbeitsTimer" to me in 1000 milliseconds
         end if   
      end startArbeitsTimer
    • #26055
      Axwald
      Teilnehmer

      Hallo,

      Der Timer-Handler holt sich die aktuelle TimerZeit aus dem dafür vorgesehenen Field, bearbeitet sie (+ 1 Sekunde) und schreibt die neue Timer-Zeit wieder in selbiges Feld zurück.

      Umständlich (und vermutlich recht ungenau). Besser einfach den Computer-Timer nutzen, über „the seconds“. Beispiel unten.

      „numberFormat“:
      Fehlerträchtig! Klaus hat erklärt, warum. „format()“ hat zwar eine ekelhafte Syntax, arbeitet aber zuverlässig: format(„%02s“, myMinute) gibt immer einen 2-stelligen Wert.


      Mein Beispiel zu diesem Problem:

      Ich merke mir die Start-Zeit (als „the seconds“) in einer globalen Variable, und setze ein Skript als „Timer-Schleife“ ein, das sich immer wieder selbst aufruft. Die abgelaufene Zeit addiere ich mir nicht zusammen, sondern errechne sie jeweils aus der Differenz „Start-Sekunden“ zu „aktuelle Sekunden“.
      Das Berechnen & Formattieren der abgelaufenen Zeit übernimmt eine eigene Funktion („secsToTime(10000)“ => „02:46:40“).

      Mein „Start“-Button:

      global gStartTime
      on mouseUp
         put the seconds into gStartTime          --  Zeit merken
         ourTimer                                 --  Timer-Schleife starten
      end mouseUp

      Die Timer-Schleife „ourTimer“ läuft im Stack-Script:

      global gStartTime
      on ourTimer what
         switch what
            case "stop"                                --  Timer stoppen, Ergebnis anzeigen:
               put secsToTime(the seconds - gStartTime) into theTime     --  Ergebnis merken
               put theTime into fld "time_fld" of cd "time_cd" of this stack    --  anzeigen
               repeat for each line L in the pendingMessages       --  Message-Queue stoppen
                  if "ourTimer" is in L then cancel item 1 of L
               end repeat
               answer "Zeit gesamt: " & theTime                     --  offizielle Zeitnahme
               put empty into gStartTime                             --  System zurücksetzen
               put empty into fld "time_fld" of cd "time_cd" of this stack
               break
            default                            --  der normale Ablauf während der Zeitnahme:
               put secsToTime(the seconds - gStartTime) into \
                     fld "time_fld" of cd "time_cd" of this stack          --  Zeit anzeigen
               send "ourTimer" to me in 1 seconds         --  und dieses Skript wieder rufen
         end switch
      end ourTimer

      Normal aufgerufen (ohne „Stop“ als Parameter) schreibt dies die vergangene Zeit in das dafür vorgesehene Feld (wir müssen dazu nicht auf der Karte sein!). Anschließend startet sich das Skript nach 1 Sekunde selber wieder.

      Mit „Stop“ wird es etwas komplizierter:
      Wir merken uns die vergangene Zeit, entfernen in der Repeat-Schleife etwaige weitere Aufrufe von „OurTimer“ aus den wartenden Messages (um das Skript zu stoppen), geben das Ergebnis bekannt und setzen das Zeit-Feld & die globale Variable zurück.

      Nun die Funktion, die aus „the seconds“ etwas Verständliches macht (im Stack-Script):

      function secsToTime theSecs
         put theSecs div 86400 into myDay                   --  erst ganze Tage 'rausrechnen
         put theSecs - (myDay * 86400) into theSecs
         put theSecs div 3600 into myHour                --  dann ganze Stunden 'rausrechnen
         put theSecs - (myHour * 3600) into theSecs
         put theSecs div 60 into myMinute                --  dann ganze Minuten 'rausrechnen
         put theSecs - (myMinute * 60) into theSecs           --  der Rest sind die Sekunden
         if myDay > 0 then                                     --  Formatieren & zurückgeben
            return myDay & " T, " & format("%02s", myHour) & ":" & \
                  format("%02s", myMinute) & ":" & format("%02s", theSecs)
         else
            return format("%02s", myHour) & ":" & \
                  format("%02s", myMinute) & ":" & format("%02s", theSecs)
         end if
      end secsToTime

      „div“ wird benutzt um herauszufinden, wieviele ganze Tage (Stunden, Minuten) in „theSecs“ enthalten sind, gemerkt & abgezogen. Das Ergebnis wird formattiert & zurückgegeben.

      Fehlt noch der „Stop“-Button:

      on mouseUp
         ourTimer "stop"
      end mouseUp

      Gar nicht so kompliziert, oder?

      Viel Spaß!

      Code mit Community Version erstellt, also GPL V3. Enthält keine plattform- oder versionsspezifischen Funktionen, sollte also überall laufen.

    • #26078
      Aldred
      Teilnehmer

      Hi Klaus und Axwald,
      Danke für eure Antworten und Erklärungen.
      Klaus, ich habs mit deiner Methode umgebaut und es läuft perfekt (Ich hab keine Sekunde daran gezweifelt 🙂 )
      Herzlichen Dank dafür.
      Und Axwald, danke für deine Erklärung. Es ist immer gut dazu zu lernen!

      Liebe Grüße
      Aldred

Ansicht von 4 Antwort-Themen
  • Du musst angemeldet sein, um auf dieses Thema antworten zu können.