EventHandler

Anfängerfragen zum Programmieren mit PureBasic.
GerhardHoeberth
Beiträge: 24
Registriert: 14.03.2015 18:22
Wohnort: Wasserburg
Kontaktdaten:

EventHandler

Beitrag 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.
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

Re: EventHandler

Beitrag 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
Zuletzt geändert von Bisonte am 24.02.2018 17:32, insgesamt 1-mal geändert.
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
GerhardHoeberth
Beiträge: 24
Registriert: 14.03.2015 18:22
Wohnort: Wasserburg
Kontaktdaten:

Re: EventHandler

Beitrag 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
Benutzeravatar
Sicro
Beiträge: 955
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: EventHandler

Beitrag 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 :)
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Benutzeravatar
DarkSoul
Beiträge: 689
Registriert: 19.10.2006 12:51

Re: EventHandler

Beitrag 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. :mrgreen:
Bild
Antworten