Counter mit Stop abbrechen und mit Start weiter zählen

Anfängerfragen zum Programmieren mit PureBasic.
Sommertv
Beiträge: 68
Registriert: 26.04.2019 10:31
Computerausstattung: Lenovo W500, Debian Stable, Purebasic 5.70 (momentan die Testversion)
Wohnort: Mühldorf am Inn

Counter mit Stop abbrechen und mit Start weiter zählen

Beitrag von Sommertv »

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: Alles auswählen

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

Wenn einem die einfachen Dinge net einfallen, klappt's meistens umständlich...
Benutzeravatar
silbersurfer
Beiträge: 174
Registriert: 06.07.2014 12:21

Re: Counter mit Stop abbrechen und mit Start weiter zählen

Beitrag von silbersurfer »

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: Alles auswählen

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
Intel Quad Core 3,2 Ghz - GTX 1060 - BlitzBasic Plus 1.48 , PureBasic 5.70 LTS / Aktuelles Projekt PureCommander
Sommertv
Beiträge: 68
Registriert: 26.04.2019 10:31
Computerausstattung: Lenovo W500, Debian Stable, Purebasic 5.70 (momentan die Testversion)
Wohnort: Mühldorf am Inn

Re: Counter mit Stop abbrechen und mit Start weiter zählen

Beitrag von Sommertv »

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: Alles auswählen

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
Wenn einem die einfachen Dinge net einfallen, klappt's meistens umständlich...
Benutzeravatar
silbersurfer
Beiträge: 174
Registriert: 06.07.2014 12:21

Re: Counter mit Stop abbrechen und mit Start weiter zählen

Beitrag von silbersurfer »

@Sommertv
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: Alles auswählen

For t=0 to 100
    If Stop
       Break
    Endif 
next
hier ein Beispiel:

Code: Alles auswählen

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
Zuletzt geändert von silbersurfer am 09.05.2019 10:36, insgesamt 1-mal geändert.
Intel Quad Core 3,2 Ghz - GTX 1060 - BlitzBasic Plus 1.48 , PureBasic 5.70 LTS / Aktuelles Projekt PureCommander
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Counter mit Stop abbrechen und mit Start weiter zählen

Beitrag von mk-soft »

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.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
silbersurfer
Beiträge: 174
Registriert: 06.07.2014 12:21

Re: Counter mit Stop abbrechen und mit Start weiter zählen

Beitrag von silbersurfer »

@mk-soft
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 ?
Intel Quad Core 3,2 Ghz - GTX 1060 - BlitzBasic Plus 1.48 , PureBasic 5.70 LTS / Aktuelles Projekt PureCommander
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Counter mit Stop abbrechen und mit Start weiter zählen

Beitrag von NicTheQuick »

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.
Bild
Benutzeravatar
silbersurfer
Beiträge: 174
Registriert: 06.07.2014 12:21

Re: Counter mit Stop abbrechen und mit Start weiter zählen

Beitrag von silbersurfer »

@NicTheQuick
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
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
Intel Quad Core 3,2 Ghz - GTX 1060 - BlitzBasic Plus 1.48 , PureBasic 5.70 LTS / Aktuelles Projekt PureCommander
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Counter mit Stop abbrechen und mit Start weiter zählen

Beitrag von NicTheQuick »

: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.
Bild
matbal
Beiträge: 246
Registriert: 30.03.2011 20:53

Re: Counter mit Stop abbrechen und mit Start weiter zählen

Beitrag von matbal »

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: Alles auswählen

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
Antworten