PureBoard
http://forums.purebasic.com/german/

Counter mit Stop abbrechen und mit Start weiter zählen
http://forums.purebasic.com/german/viewtopic.php?f=16&t=31455
Seite 1 von 2

Autor:  Sommertv [ 08.05.2019 23:33 ]
Betreff des Beitrags:  Counter mit Stop abbrechen und mit Start weiter zählen

Schönen Abend,

wie erreiche ich, dass beim Drücken der Stop Taste der Zähler anhält und bei Start wieder weiter läuft?
Danke im Vorab... Kurt


Code:
Enumeration
  #Counter
  #String0
  #BtnStart
  #BtnStop
EndEnumeration

Procedure Open_Counter()
  OpenWindow(#Counter, 853, 168, 600, 440, "Counter")
    StringGadget(#String0, 0, 5, 240, 25, "0")
    ButtonGadget(#BtnStart, 0, 30, 120, 25, "Start")
    ButtonGadget(#BtnStop, 120, 30, 120, 25, "Stop")
EndProcedure

Open_Counter()

Define.l Event, EventWindow, EventGadget, EventType, EventMenu
; Event Schleife
Repeat
  Event = WaitWindowEvent()
  Select Event
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    Case #PB_Event_Menu
      EventMenu = EventMenu()
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    Case #PB_Event_Gadget
      EventGadget = EventGadget()
      If EventGadget = #String0
      ElseIf EventGadget = #BtnStart
          For i=1 To 1000
            a$=Str(i)
            SetGadgetText(#String0,a$)
            While WindowEvent():Wend ; updaten
            Delay (50)
          Next   
      ElseIf EventGadget = #BtnStop
      EndIf
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    Case #PB_Event_CloseWindow
      EventWindow = EventWindow()
      If EventWindow = #Counter
        CloseWindow(#Counter)
        End
      EndIf
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  EndSelect
ForEver


Autor:  silbersurfer [ 09.05.2019 01:08 ]
Betreff des Beitrags:  Re: Counter mit Stop abbrechen und mit Start weiter zählen

Hallo Sommertv,
vorab erstmal solltes du nur ein WaitWindowEvent() ausführen, da ansonsten Events verschluckt werden können.
Da WaitWindowEvent() solange wartet bis ein Event ausgelöst ist gibt es mehrere möglichkeiten

  • man kann einmal einen Timeout angeben so wird die Eventschleife auch wenn kein Event ausgelöst wurde weiter durchlaufen
    WaitWindowEvent(Zeit in Milisekunden)
  • oder man erstellt einen WindowTimer der dann immer angesprungen wird
    AddWindowTimer(Window,Timer,Milisekunden)

hier ein Beispiel mit AddWindowTimer()
Code:
EnableExplicit

Enumeration
  #Counter
  #String0
  #BtnStart
  #BtnStop
  #MeinTimer
EndEnumeration

Define.l Event, EventWindow, EventGadget, EventType, EventMenu,Start,Zahl

Procedure Open_Counter()
  OpenWindow(#Counter, 853, 168, 600, 440, "Counter")
    StringGadget(#String0, 0, 5, 240, 25, "0")
    ButtonGadget(#BtnStart, 0, 30, 120, 25, "Start")
    ButtonGadget(#BtnStop, 120, 30, 120, 25, "Stop")
    AddWindowTimer(#Counter, #MeinTimer, 500) ;1000ms= 1sec
EndProcedure
Open_Counter()

; Event Schleife
Repeat
   Event = WaitWindowEvent()
   Select Event
      Case #PB_Event_Timer
         If EventTimer()=#MeinTimer
            If Start
               SetGadgetText(#String0,Str(Zahl))
               Zahl+1
            Else
               Zahl=0 : SetGadgetText(#String0,Str(Zahl))
            EndIf   
         EndIf   
      Case #PB_Event_Menu
         EventMenu = EventMenu()
      Case #PB_Event_Gadget
         EventGadget = EventGadget()
         If EventGadget = #String0
         ElseIf EventGadget = #BtnStart
            Start=#True
         ElseIf EventGadget = #BtnStop
            Start=#False : Zahl=0
         EndIf
      Case #PB_Event_CloseWindow
         EventWindow = EventWindow()
         If EventWindow = #Counter
            CloseWindow(#Counter)
            End
         EndIf
   EndSelect
ForEver

Autor:  Sommertv [ 09.05.2019 08:19 ]
Betreff des Beitrags:  Re: Counter mit Stop abbrechen und mit Start weiter zählen

Uii, danke... jetzt leuchtet mir so einiges ein...
Lässt sich eine for - next Schleife auch auf diese Weise beeinflussen?
Falls net, auch egal, dann merk ich mir den Augenblickswert in einer Variable.

Danke nochmal
Kurt


Hab das gleich nochmal erweitert:

Code:
EnableExplicit

Enumeration
  #Counter
  #String0
  #BtnStart
  #BtnStop
  #BtnReset
  #MeinTimer
EndEnumeration

Define.l Event, EventWindow, EventGadget, EventType, EventMenu,Start,Zahl, StopFlag

Procedure Open_Counter()
  OpenWindow(#Counter, 853, 168, 600, 440, "Counter")
    StringGadget(#String0, 0, 5, 240, 25, "0")
    ButtonGadget(#BtnStart, 0, 30, 80, 25, "Start")
    ButtonGadget(#BtnStop, 80, 30, 80, 25, "Stop")
    ButtonGadget(#BtnReset, 160,30,80,25, "Reset")
    AddWindowTimer(#Counter, #MeinTimer, 500) ;1000ms= 1sec
EndProcedure
Open_Counter()

; Event Schleife
Repeat
  Event = WaitWindowEvent()
   Select Event
      Case #PB_Event_Timer
         If EventTimer()=#MeinTimer
            If Start
               SetGadgetText(#String0,Str(Zahl))
                 If StopFlag = 1
                   Zahl+1
                 EndIf
             Else
               SetGadgetText(#String0,Str(Zahl))
            EndIf   
         EndIf   
      Case #PB_Event_Menu
         EventMenu = EventMenu()
      Case #PB_Event_Gadget
         EventGadget = EventGadget()
         If EventGadget = #String0
         ElseIf EventGadget = #BtnStart
           Start=#True
           StopFlag = 1
         ElseIf EventGadget = #BtnStop
           Start=#False
           StopFlag = 0
         ElseIf EventGadget = #BtnReset
           Start=#False : Zahl = 0
         EndIf
       Case #PB_Event_CloseWindow
         EventWindow = EventWindow()
         If EventWindow = #Counter
            CloseWindow(#Counter)
            End
         EndIf
   EndSelect
ForEver

Autor:  silbersurfer [ 09.05.2019 09:15 ]
Betreff des Beitrags:  Re: Counter mit Stop abbrechen und mit Start weiter zählen

@Sommertv
Zitat:
Lässt sich eine for - next Schleife auch auf diese Weise beeinflussen?

Ja mann kann so ganze Proceduren automatisch aufrufen (auch For Next Schleifen),
zudem ist es auch möglich mehere Timer zu verwenden.

Edit: wenn mann in einer Schleife einen Abbruch machen möchte gibt es dafür den Befehl Break, das gilt für alle Schleifen in Purebasic
Code:
For t=0 to 100
    If Stop
       Break
    Endif
next


hier ein Beispiel:
Code:
EnableExplicit

Enumeration
  #Counter
  #String0
  #BtnStart
  #BtnStop
  #BtnReset
  #MeinTimer
  #MeinTimer2
EndEnumeration

Define.l Event, EventWindow, EventGadget, EventType, EventMenu,Start,Zahl, StopFlag,Eintrag,t

Procedure Open_Counter()
  OpenWindow(#Counter, 853, 168, 600, 440, "Counter")
    StringGadget(#String0, 0, 5, 240, 25, "0")
    ButtonGadget(#BtnStart, 0, 30, 80, 25, "Start")
    ButtonGadget(#BtnStop, 80, 30, 80, 25, "Stop")
    ButtonGadget(#BtnReset, 160,30,80,25, "Reset")
    AddWindowTimer(#Counter, #MeinTimer, 500) ;1000ms= 1sec
    AddWindowTimer(#Counter, #MeinTimer2, 2500) ;1000ms= 1sec
EndProcedure
Open_Counter()

; Event Schleife
Repeat
  Event = WaitWindowEvent()
   Select Event
      Case #PB_Event_Timer
         If EventTimer()=#MeinTimer
            If Start
               SetGadgetText(#String0,Str(Zahl))
                 If StopFlag = 1
                   Zahl+1
                 EndIf
             Else
               SetGadgetText(#String0,Str(Zahl))
           EndIf
           Eintrag+25 : If Eintrag> 255 : eintrag=0 : EndIf
       ElseIf EventTimer()=#MeinTimer2
          SetWindowColor(#Counter,RGB(200,200,eintrag))
          For t =0 To 5
                 If StopFlag=0
                Debug "schleife wurde unterbrochen"
                Break
             EndIf    
           Debug "mache irgendwas"
          Next    
        Endif     
      Case #PB_Event_Menu
         EventMenu = EventMenu()
      Case #PB_Event_Gadget
         EventGadget = EventGadget()
         If EventGadget = #String0
         ElseIf EventGadget = #BtnStart
           Start=#True
           StopFlag = 1
         ElseIf EventGadget = #BtnStop
           Start=#False
           StopFlag = 0
         ElseIf EventGadget = #BtnReset
           Start=#False : Zahl = 0
         EndIf
       Case #PB_Event_CloseWindow
         EventWindow = EventWindow()
         If EventWindow = #Counter
            CloseWindow(#Counter)
            End
         EndIf
   EndSelect
ForEver

Autor:  mk-soft [ 09.05.2019 10:27 ]
Betreff des Beitrags:  Re: Counter mit Stop abbrechen und mit Start weiter zählen

Eine For/Next schleife hat in ein Event Management nichts zu suchen
Meldung "Fenster reagiert nicht mehr" da die Events in diesen Zeitpunkt nicht mehr verarbeitet werden.

Autor:  silbersurfer [ 09.05.2019 10:40 ]
Betreff des Beitrags:  Re: Counter mit Stop abbrechen und mit Start weiter zählen

@mk-soft
Zitat:
Eine For/Next schleife hat in ein Event Management nichts zu suchen


wie meinst du das jetzt, mein For Next hat nicht mit den Eventmangement zu tun, diese wird nur ausgeführt
oder war ich jetzt garnicht gemeint ?

Autor:  NicTheQuick [ 09.05.2019 10:58 ]
Betreff des Beitrags:  Re: Counter mit Stop abbrechen und mit Start weiter zählen

Deine For-Schleife im #MeinTimer2-Fall kann gar nicht durch das StopFlag unterbrochen werden, weil StopFlag nicht geändert werden kann während die Schleife läuft. Du hast ja in deinem Programm keine Nebenläufigkeit, sprich Threads, mit denen das möglich wäre. Wäre das eine längere Schleife, die Zeit braucht, würde damit die Ereignisschleife aufgehalten werden und es würde zum "Anwendung reagiert nicht mehr"-Szenario kommen.

Autor:  silbersurfer [ 09.05.2019 18:12 ]
Betreff des Beitrags:  Re: Counter mit Stop abbrechen und mit Start weiter zählen

@NicTheQuick
Zitat:
Fall kann gar nicht durch das StopFlag unterbrochen werden

das ist schon Klar das sie so nicht unterbrochen wird, aber sobald der Stopflag gesetzt ist wird diese nicht mehr ausgeführt.
zudem sollte das auch nur zeigen was machbar ist, wenn man z.b. auf neue Daten checken möchte die immer wieder geprüft werden sollen u.s.w

Zitat:
Wäre das eine längere Schleife

ja das weiß ich auch, nun stellte ich mir doch gleich die frage wir ihr dann programme ohne Threads schreibt, ohne Schleifen oder Proceduren ? In denen Schleifen irgendwas abarbeiten , das ist nähmlich nichts anderes wenn dort z.b irgendwelche dinge länger dauern so wird das Programm dort auch warten bis es erledigt ist (ohne weitere Events abzuarbeiten).
und einen Anfänger gleich mit Threads zu bombadieren wäre ja wohl zu viel des guten

Autor:  NicTheQuick [ 09.05.2019 19:50 ]
Betreff des Beitrags:  Re: Counter mit Stop abbrechen und mit Start weiter zählen

:allright:

Ich wollte tatsächlich nur nicht, dass du Sommertv auf die falsche Fährte bringst. Immerhin war das Problem in seinem ersten Post ja die For-Schleife, die zu lange braucht und gleichzeitig sogar noch Gadgetinhalte änderte. Da du jetzt wieder beispielhaft eine wenn auch kurze Schleife eingebaut hast, sieht das so aus als seien Schleifen doch wieder nicht so schlimm. Im Endeffekt kommt es aber nur darauf an, dass stetig Events abgearbeitet werden können. Kurze Ruckler, selbst wenn es mal eine Sekunde ist, werden vielleicht kaum bemerkt, aber sobald das öfter und regelmäßig passiert, hat der Anwender vielleicht keine Lust mehr die Anwendung zu nutzen, weil sie träge erscheint.

Autor:  matbal [ 09.05.2019 19:58 ]
Betreff des Beitrags:  Re: Counter mit Stop abbrechen und mit Start weiter zählen

Ich hatte früher einfach den EventLoop in eine Prozedur gepackt. Damit konnte ich auch in einer länger andauernden Schleife Events abarbeiten. DoEvents() enthält im Beispiel den EventLoop.

Mit BindEvent() funktioniert dieser Trick aber nicht mehr.

Code:
EnableExplicit

Enumeration
   #FormMain
EndEnumeration

Enumeration
   #FormMain_Button_Start
   #FormMain_Button_Stop
   #FormMain_Text_Time
EndEnumeration

Enumeration
   #Font_Time
EndEnumeration


Global gStop

Define.l Event

Declare DoEvents(timeout = #PB_Default)

Procedure FormMain_Button_Start_OnEvent(EventType)

   Protected i
   Protected max = 1000
   gStop = 0
   
   DisableGadget(#FormMain_Button_Start, 1)
   DisableGadget(#FormMain_Button_Stop, 0)
   
   ; Arbeit begonnen
   For i = 1 To max
      Delay(10)   ; Hier sollte eigentlich etwas abgearbeitet werden
     
      SetGadgetText(#FormMain_Text_Time, StrD(i*100/max, 1) + "%") ; Fortschritt
      DoEvents(0) ; Events verarbeiten
     
      If gStop
         Break
      EndIf
   Next i
   ; Arbeit beendet
   
   DisableGadget(#FormMain_Button_Stop, 1)
   DisableGadget(#FormMain_Button_Start, 0)
   
EndProcedure

Procedure FormMain_Button_Stop_OnEvent(EventType)
   
   gStop = 1
   
EndProcedure


Procedure FormMain_Open()
   
   If OpenWindow(#FormMain, 464, 219, 321, 136, "Programm", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_TitleBar | #PB_Window_MaximizeGadget)
      ButtonGadget(#FormMain_Button_Start, 15, 95, 80, 25, "Start")
      ButtonGadget(#FormMain_Button_Stop, 100, 95, 80, 25, "Stop")
      DisableGadget(#FormMain_Button_Stop, 1)
      TextGadget(#FormMain_Text_Time, 15, 10, 295, 75, "", #PB_Text_Center)
      LoadFont(#Font_Time, "Arial", 50)
      SetGadgetFont(#FormMain_Text_Time, FontID(#Font_Time))
   EndIf
   
EndProcedure

Procedure FormMain_Close()
   
   CloseWindow(#FormMain)
   End
   
EndProcedure



Procedure DoEvents(timeout = #PB_Default)
   Protected Event
   
   Event = WaitWindowEvent(timeout)
   While Event
      Select Event
            ; ///////////////////
         Case #PB_Event_Gadget
            Select EventGadget()
               Case #FormMain_Button_Start
                  FormMain_Button_Start_OnEvent(EventType())
               Case #FormMain_Button_Stop
                  FormMain_Button_Stop_OnEvent(EventType())
               Case #FormMain_Text_Time
            EndSelect
            ; ////////////////////////
         Case #PB_Event_CloseWindow
            Select EventWindow()
               Case #FormMain
                  FormMain_Close()
            EndSelect
           
      EndSelect
      event = WindowEvent()
   Wend
   
EndProcedure



FormMain_Open()

Repeat
   DoEvents()
ForEver

Seite 1 von 2 Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/