Seite 1 von 2
Counter mit Stop abbrechen und mit Start weiter zählen
Verfasst: 08.05.2019 23:33
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
Re: Counter mit Stop abbrechen und mit Start weiter zählen
Verfasst: 09.05.2019 01:08
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
Re: Counter mit Stop abbrechen und mit Start weiter zählen
Verfasst: 09.05.2019 08:19
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
Re: Counter mit Stop abbrechen und mit Start weiter zählen
Verfasst: 09.05.2019 09:15
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
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
Re: Counter mit Stop abbrechen und mit Start weiter zählen
Verfasst: 09.05.2019 10:27
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.
Re: Counter mit Stop abbrechen und mit Start weiter zählen
Verfasst: 09.05.2019 10:40
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 ?
Re: Counter mit Stop abbrechen und mit Start weiter zählen
Verfasst: 09.05.2019 10:58
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.
Re: Counter mit Stop abbrechen und mit Start weiter zählen
Verfasst: 09.05.2019 18:12
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
Re: Counter mit Stop abbrechen und mit Start weiter zählen
Verfasst: 09.05.2019 19:50
von NicTheQuick
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.
Re: Counter mit Stop abbrechen und mit Start weiter zählen
Verfasst: 09.05.2019 19:58
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