ExitLoop auf Button

  • Ich fang gleich ein zu weinen... ;(
    Seit einer Stunde such ich bereits auf Google und in sämmtlichen Foren weil ich nicht glauben kann das es dazu nichts gibt.
    Aber nun bin ich einfach gezwungen euch nocheinmal zu belästigen. Sry!

    Ich wollte eigendlich ein Minispiel machen und bin schonwieder, gleich am Anfang, auf ein Fehler gestoßen..
    Hab es schon auf 5 verschiedene Arten versucht zu schreiben aber wenn ihr das hier seht..
    So wie es jetzt da steht, versteht ihr sicherlich am schnellsten was ich meine.

    (das mit dem "Sleep ($Text)" ist nur aus spaß da.. :D )

    Das Problem:
    Ich komme aus der Schleife einfach nicht wieder raus.
    Es gibt eine Lösung für mein Problem die ich selber kenne...
    HotKeySet ("{DEL}", "_Pause") ; <- Zwingt quasi das Script auf die "Func _Pause()" zu springen.

    aber mal im ernst..
    Ich will kein Hotkey benutzen ............ ;(
    Wieso kann man den Button nicht genauso zwingen wie ein Hotkey? :cursing:

    Bin sehr verwirrt das es so schwer ist mit einem Button aus einer Schleife zu kommen..
    Ich verstehe inzwischen wieso das so ist... ich denke der "Stop" Button wird garnicht erst angesprochen weil die schleife vom "Start" button nicht bisdahin reicht.

    Nunja, ich bin mit meinem Latein aber nun wirklich am Ende..
    Daher wende ich mich mal wieder an euch.. :D

    Script:

    Spoiler anzeigen
    [autoit]

    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $Loop = False

    [/autoit] [autoit][/autoit] [autoit]

    #Region ### START Koda GUI section ### Form=
    $GUI = GUICreate("Test", 187, 146, 854, 446)
    $Text = GUICtrlCreateEdit("", 8, 8, 169, 81, BitOR($GUI_SS_DEFAULT_EDIT,$ES_CENTER))
    GUICtrlSetData(-1, "0")
    $Start = GUICtrlCreateButton("Start", 8, 112, 75, 25)
    $Stop = GUICtrlCreateButton("Stop", 104, 112, 75, 25)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

    Case $Start
    $Loop = True
    While $Loop
    Sleep (GUICtrlRead($Text))
    GUICtrlSetData($Text, GUICtrlRead($Text)+1)
    WEnd ; <--- Wie komm ich aus dieser Schleife mit einem Button wieder raus? :(

    Case $Stop
    $Loop = False
    ExitLoop 1

    EndSwitch
    WEnd

    [/autoit]

    Wer will soll einfach mal Kopieren und einmal im Editor starten..
    Da wird SEHR deutlich wo das Problem liegt.


    Sorry.. nächstes mal versuche ich mich kürzer zu fassen.. :S
    Danke Schonmal für jeden Tipp :!:

    Wer Rechtschreibfehler findet darf sie behalten. :D

    Einmal editiert, zuletzt von ThirtySix (8. Juli 2013 um 12:43)

  • Hi, die Idee war gut, nur die Umsetzung nicht :D

    Spoiler anzeigen
    [autoit]

    #include <ButtonConstants.au3>
    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $Loop = False

    [/autoit] [autoit][/autoit] [autoit]

    #region ### START Koda GUI section ### Form=
    $GUI = GUICreate("Test", 187, 146, 854, 446)
    $Text = GUICtrlCreateEdit("", 8, 8, 169, 81, BitOR($GUI_SS_DEFAULT_EDIT, $ES_CENTER))
    GUICtrlSetData(-1, "0")
    $Start = GUICtrlCreateButton("Start", 8, 112, 75, 25)
    $Stop = GUICtrlCreateButton("Stop", 104, 112, 75, 25)
    GUISetState(@SW_SHOW)
    #endregion ### END Koda GUI section ###

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit

    [/autoit] [autoit][/autoit] [autoit]

    Case $Start
    $Loop = True

    [/autoit] [autoit][/autoit] [autoit]

    Case $Stop
    $Loop = False
    ExitLoop 1

    [/autoit] [autoit][/autoit] [autoit]

    EndSwitch

    [/autoit] [autoit][/autoit] [autoit]

    If $Loop Then ;solange $loop=true, zahlen erhöhen
    Sleep(GUICtrlRead($Text))
    GUICtrlSetData($Text, GUICtrlRead($Text) + 1)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit]
  • Wieso hab ich dazu gestern nichts gefunden ? D:
    Naja... zumglück doch nicht so kompliziert!

    wieder was gelernt!

    Danke Andy! :D

    Wer Rechtschreibfehler findet darf sie behalten. :D

  • Du hast deshalb nix gefunden, weil es simple Logik ist. Wenn das Programm in die Schleife geht, wie soll es dann daraus kommen um zu dem $Stop zu gehen um $Loop zu ändern?

    • Offizieller Beitrag

    Andy: Deine Umsetzung ist auch nicht so ideal. Man sollte kein Sleep in die MsgLoop-Schleife packen. Das führt dazu, dass (wenn der Sleep-Wert zu groß ist) die Buttons gar nicht mehr abgefragt werden.
    Also entweder den OnEventMode benutzen (in der Endlosschleife dort ist ein Sleep ja sogar angebracht) oder beim MsgLoop-Modus einen Timer verwenden.

  • Oscar hat natürlich Recht! :thumbup:
    Generell gehören die Sleeps() nicht in eine GuiGetMsg()-Schleife. Im vorliegenden Fall gings eher um die Logik, und bei "kleinen" Sleeps taucht das Problem auch nicht auf :whistling:

  • [...] Also entweder den OnEventMode benutzen (in der Endlosschleife dort ist ein Sleep ja sogar angebracht) oder beim MsgLoop-Modus einen Timer verwenden.

    Okay.

    Was macht "OnEventMode" & wie benutze ich nen Timer? 8|

    // edit:
    "MsgLoop-Modus" ist der nicht "OnEventMode" versteh ich das richtig? .. also quasi default einstellung?

    Wer Rechtschreibfehler findet darf sie behalten. :D

  • Das sind zwei unterschiedliche Methoden.
    Bei der Abfrage per GuiGetMsg() läufst du gewissermassen "zu Fuß" ständig durch die Liste der Windows-Ereignisse (Events) und wartest bis bspw. das passende "Buttonpressed"-Ereignis in der Liste auftaucht. Dann kannst du z.B. eine Funktion anspringen und dieses Ereignis auswerten.
    Beim OnEventMode verknüpfst du ein Ereignis (Event) mit einer selbstgeschriebene Funktion und überlässt Windows das komplette Handling. Sobald das Ereignis abgefeuert wurde, ruft Windows deine Funktion auf. Das ist zwar "schöner" aber auch etwas aufwendiger zu implementieren.

    Zu Anfang sind die Scripte nicht so aufwendig, dass man den OnEventMode bräuchte^^

  • Je komplexer ein Programm wird und je mehr einzelne Fenster es in dem Programm gibt, desto eher brauchst du den OnEvent-Mode. Bei mir laufen gut 90% der Scripte im OnEvent-Mode. Eigentlich verwende ich den nur noch. Der macht einfach vieles einfacher.


  • Das sind zwei unterschiedliche Methoden.
    Bei der Abfrage per GuiGetMsg() läufst du gewissermassen "zu Fuß" ständig durch die Liste der Windows-Ereignisse (Events) und wartest bis bspw. das passende "Buttonpressed"-Ereignis in der Liste auftaucht. Dann kannst du z.B. eine Funktion anspringen und dieses Ereignis auswerten.
    Beim OnEventMode verknüpfst du ein Ereignis (Event) mit einer selbstgeschriebene Funktion und überlässt Windows das komplette Handling. Sobald das Ereignis abgefeuert wurde, ruft Windows deine Funktion auf. Das ist zwar "schöner" aber auch etwas aufwendiger zu implementieren.

    Zu Anfang sind die Scripte nicht so aufwendig, dass man den OnEventMode bräuchte^^


    Je komplexer ein Programm wird und je mehr einzelne Fenster es in dem Programm gibt, desto eher brauchst du den OnEvent-Mode. Bei mir laufen gut 90% der Scripte im OnEvent-Mode. Eigentlich verwende ich den nur noch. Der macht einfach vieles einfacher.

    Okay...
    Ich werd mir das mal ansehen und versuchen zu verstehen...
    Wenn das besser ist und "vieles einfacher" macht will ich das natürlich auch benutzen :'D

    Wer Rechtschreibfehler findet darf sie behalten. :D

    • Offizieller Beitrag

    Im OnEventMode würde das Beispiel so aussehen:

    Spoiler anzeigen
    [autoit]


    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt('GUIOnEventMode', 1) ; OnEventMode für die GUI

    [/autoit] [autoit][/autoit] [autoit]

    Global $Loop = False

    [/autoit] [autoit][/autoit] [autoit]

    #region ### START Koda GUI section ### Form=
    $GUI = GUICreate("Test", 187, 146, 854, 446)
    GUISetOnEvent($GUI_EVENT_CLOSE, '_Exit') ; beim Klick auf das Schliessen-Symbol wird die Funktion '_Exit' aufgerufen
    $Text = GUICtrlCreateEdit("", 8, 8, 169, 81, BitOR($GUI_SS_DEFAULT_EDIT, $ES_CENTER))
    GUICtrlSetData(-1, "0")
    $Start = GUICtrlCreateButton("Start", 8, 112, 75, 25)
    GUICtrlSetOnEvent(-1, '_Start') ; beim Klick auf [Start] wird die Funktion '_Start' aufgerufen
    $Stop = GUICtrlCreateButton("Stop", 104, 112, 75, 25)
    GUICtrlSetOnEvent(-1, '_Stop') ; beim Klick auf [Stop] wird die Funktion '_Stop' aufgerufen
    GUISetState(@SW_SHOW)
    #endregion ### END Koda GUI section ###

    [/autoit] [autoit][/autoit] [autoit]

    While Sleep(10) ; Sleep(10) damit das Script nicht 100% Rechenlast benötigt
    If $Loop Then ;solange $loop=true, zahlen erhöhen
    Sleep(GUICtrlRead($Text))
    GUICtrlSetData($Text, GUICtrlRead($Text) + 1)
    EndIf
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

    [/autoit] [autoit][/autoit] [autoit]

    Func _Start()
    $Loop = True
    EndFunc ;==>_Start

    [/autoit] [autoit][/autoit] [autoit]

    Func _Stop()
    $Loop = False
    EndFunc ;==>_Stop

    [/autoit]

  • Im OnEventMode würde das Beispiel so aussehen:
    [...]

    Wow. Danke.

    Ich glaub das gefällt mir :'D

    Ich werd mich ab Morgen intensiv damit auseinandersetzen..
    Vielen Dank :)

    In diesem Forum fehlt wirklich soein "Like / Thumbs up / Bewertungs" - system ..
    Ihr hättet das aufjedenfall verdient :thumbup:

    Ist ja nicht selbstverständlich solche Hilfestellungen zu geben :huh:

    Wer Rechtschreibfehler findet darf sie behalten. :D

  • Zitat

    Ist ja nicht selbstverständlich solche Hilfestellungen zu geben

    Hier schon, genau deshalb brauchen wir so ein LIKE-Gedöns auch nicht...

  • Hier schon, genau deshalb brauchen wir so ein LIKE-Gedöns auch nicht...

    Okay... 8|

    Ich finds nachwievor nicht selbstverständlich.. :D
    Aber wenn ihr das tut ist das Super :thumbup:

    Wer Rechtschreibfehler findet darf sie behalten. :D

  • Das wäre noch ne Variante ohne der Variable $Loop.

    Spoiler anzeigen
    [autoit]

    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Opt('GUIOnEventMode', 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global $cEdit, $cStart, $cStop

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    GUICreate("Test", 180, 130)
    $cEdit = GUICtrlCreateEdit("0", 5, 5, 170, 80, $ES_CENTER)
    $cStart = GUICtrlCreateButton("Start", 5, 100, 80, 25)
    $cStop = GUICtrlCreateButton("Stop", 95, 100, 80, 25)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    GUISetOnEvent($GUI_EVENT_CLOSE, '_Exit')
    GUICtrlSetOnEvent($cStart, '_Start')
    GUICtrlSetOnEvent($cStop, '_Stop')

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While Sleep(10)
    If BitAND(GUICtrlGetState($cStart), $GUI_DISABLE) = $GUI_DISABLE Then
    Sleep(GUICtrlRead($cEdit))
    GUICtrlSetData($cEdit, GUICtrlRead($cEdit) + 1)
    EndIf
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Start()
    GUICtrlSetState($cStart, $GUI_DISABLE)
    GUICtrlSetState($cStop, $GUI_ENABLE)
    EndFunc ;==>_Start

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Stop()
    GUICtrlSetState($cStop, $GUI_DISABLE)
    GUICtrlSetState($cStart, $GUI_ENABLE)
    EndFunc ;==>_Stop

    [/autoit]
    • Offizieller Beitrag

    Naja, man muss mehr Funktionen schreiben, aber eigentlich ist der OnEventMode einfacher (IMHO). Vorrausgesetzt man hat erstmal verstanden, wie der Modus funktioniert.
    Wichtig ist nämlich, dass in den Funktionen, die per GUISetOnEvent oder GUICtrlSetOnEvent aufgerufen werden, möglichst kein Sleep oder eine Endlosschleife vorhanden ist.
    Solange wie man diese Funktionen nicht wieder verlässt, solange werden keine weiteren GUI-Events ausgewertet. Diese "Event-Funktionen" sollten also eine möglichst kurze Laufzeit aufweisen, um die Benutzeroberfläche bedienbar zu halten.