Seite 1 von 1
EventHandler
Verfasst: 24.02.2018 17:10
von GerhardHoeberth
Hallo in die Runde
Wie kann ich aus einer laufenden Schleife (For Next) aussteigen, indem ich einen Button ("Stop"-ButtonGadget) klicke?
Ich habe ins Hauptprogramm folgendes geschrieben:
Code: Alles auswählen
Repeat
pgrlauf = Window_0_Events(WaitWindowEvent())
Until pgrlauf = #False
End
Procedure Window_0_Events(event)
Select event
Case #PB_Event_CloseWindow
ProcedureReturn #False
Case #PB_Event_Menu
Select EventMenu()
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
...
Case btmStop
StoppBerechnung(EventType())
...
EndSelect
EndSelect
ProcedureReturn #True
EndProcedure
; Innerhalb der OpenWindow Procedure steht:
Code: Alles auswählen
btmStop = ButtonGadget(#PB_Any, 20, 60, 40, 20, "Stop")
GadgetToolTip(btmStop, "Stoppt die Berechnung")
; aufgerufen wird damit diese Procedure:
Code: Alles auswählen
Procedure StoppBerechnung(EventType)
Anhalten = 1
EndProcedure
Und innerhalb der For-Next-Schleife habe ich folgenden code eingefügt:
Code: Alles auswählen
If Anhalten = 1
Anhalten = 0
StatusBarText(0, 0, "Berechnung abgebrochen")
Break
EndIf
... funktioniert aber nicht

Das Programm meldet dann nur "Keine Rückmeldung" und rechet im Hintergrund weiter.
Re: EventHandler
Verfasst: 24.02.2018 17:22
von Bisonte
Das ist eigentlich nur mit einem Thread machbar... Da du innerhalb deiner Schleife keine WindowEvents abfragst.
Da kann man dann völlig vergebens auf den Button einklicken.... das Event, das er geklickt wurde kommt erst an wenn die Schleife durch ist.
Edit :
Kurzes Beispiel :
Code: Alles auswählen
Enumeration #PB_Event_FirstCustomValue
#SchleifenEnde
EndEnumeration
Global ThreadAnhalten = #False
Procedure.i Thread(Dummy.i)
For x = 0 To 200000000
If ThreadAnhalten = #True ; Hier aussteigen, wenn Button gedrückt wird
; Ich sende nochmal ein Event um zu zeigen wo denn die Schleife abbrach
PostEvent(#SchleifenEnde, 0, 0, 0, x)
Break
EndIf
; Berechne hier und Da ich simuliere das mal mit einem Delay
Delay(10)
Next x
EndProcedure
Define Event, Quit
OpenWindow(0, 0, 0, 640, 480, "Test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ButtonGadget(1, 20, 20, 200, 25, "Starte Schleife")
ButtonGadget(2, 20, 60, 200, 25, "Stoppe Schleife")
TextGadget(3, 20, 90, 200, 25, "Schleife ist bei x")
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_CloseWindow
Quit = #True
Case #PB_Event_Gadget
Select EventGadget()
Case 1
If Not IsThread(T)
ThreadAnhalten = #False
T = CreateThread(@Thread(), 0)
EndIf
Case 2
ThreadAnhalten = #True
;
EndSelect
Case #SchleifenEnde
SetGadgetText(3, "SchleifenAbbruch bei x = " + Str(EventData()))
EndSelect
Until Quit
Re: EventHandler
Verfasst: 24.02.2018 17:32
von GerhardHoeberth
Danke für die schnelle Antwort.
ich merke immer mehr, dass ich null ahnung hab

Ich habe auch gerade bemerkt, dass das selbe passiert (keine Rückmeldung), wenn ich - während das Programm die Schleife berechnet - das Fenster verschiebe.
Was ein Thread ist und wie man das dann handhabt weiß ich auch nicht.
Gibts eigentlich brauchbare Tutorials für PureBasic, in denen man sowas erklärt bekommt
EDIT: Oh, wow Danke!
das arbeite ich jetzt erst einmal durch..
herzlichen Gruß
Gerhard
Re: EventHandler
Verfasst: 25.02.2018 01:08
von Sicro
Ich habe mal deine genannten Codes hergenommen und kurz zu einem lauffähigen Code vervollständigt:
Code: Alles auswählen
Global Anhalten, btmStop
Procedure Open_Window_0()
If OpenWindow(0, #PB_Ignore, #PB_Ignore, 200, 200, "Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If CreateStatusBar(0, WindowID(0))
AddStatusBarField(#PB_Ignore)
EndIf
btmStop = ButtonGadget(#PB_Any, 20, 60, 40, 20, "Stop")
GadgetToolTip(btmStop, "Stoppt die Berechnung")
EndIf
EndProcedure
Procedure StoppBerechnung(EventType)
Anhalten = 1
EndProcedure
Procedure Window_0_Events(event)
Select event
Case #PB_Event_CloseWindow
CloseWindow(EventWindow())
End
Case #PB_Event_Menu
Select EventMenu()
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
;...
Case btmStop
StoppBerechnung(EventType())
;...
EndSelect
EndSelect
ProcedureReturn event ; event hat den Wert Null, wenn es keine Events zum Verarbeiten gibt
EndProcedure
Open_Window_0()
For i = 1 To 1000000000 ; Sehr zeitaufwändige Schleife
If Anhalten = 1
StatusBarText(0, 0, "Berechnung abgebrochen")
Break
EndIf
; Hier dein Code, der bei jedem Schleifendurchlauf verarbeitet werden soll
; ...........
; ...........
; ...........
; So, wir sollten mal wieder Events abarbeiten, sonst denkt das Betriebssystem das Programm sei abgestürzt
While Window_0_Events(WindowEvent()) : Wend ; Events so lange verarbeiten, bis keine mehr da sind
Next
Repeat
Window_0_Events(WaitWindowEvent())
ForEver
So funktioniert es auch ohne einem Thread

Re: EventHandler
Verfasst: 25.02.2018 19:49
von DarkSoul
Ich würde WindowEvent() aber nicht in jedem Schleifenaufruf aufrufen. Das bremst die Schleife stark aus.
Jeder 1000. Schleifedurchlauf reicht da sicher auch

.
Ein Thread ist IMHO die einzig wahre Lösung für solche Monster-Rechenschleifen.
