Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   [решено] Досрочный выход из цикла (http://forum.oszone.net/showthread.php?t=328652)

Атос 27-07-2017 10:43 2754361

Досрочный выход из цикла
 
Привет.

Подскажите, а как я могу досрочно выйти из цикла?

Т.е., выход из скрипта ( или завершение работы цикла) на любой итерации цикла, по нажатию кнопки "Stop".


Код:


$hgui = GUICreate("111", 500, 300, -1, -1)
Local $s1 = GUICtrlCreateButton('Start', 100, 10, 50, 22, 0x0)
Local $s2 = GUICtrlCreateButton('Stop', 100, 50, 50, 22, 0x0)

GUISetState()

While 1
Switch GUIGetMsg()
Case -3
Exit
Case $s1
For $i = 1 To 5
MsgBox(0, '222', '333', 1)
Sleep(3000)
Next
Case $s2
Exit
EndSwitch
Wend


Mike909 27-07-2017 10:58 2754366

ExitLoop

Атос 27-07-2017 11:30 2754378

Mike909, пока цикл не дойдёт до конца, у меня не получается, ни Exit ни ExitLoop.

Mike909 27-07-2017 18:14 2754473

Как-же получится, если внутри цикла
Код:

                       
For $i = 1 To 5
        MsgBox(0, '222', '333', 1)
        Sleep(3000)
Next

сообщения от кнопок никак не обрабатываются?

For нужно делать тогда уж снаружи Switch.

Creat0R 27-07-2017 18:26 2754475

Нужен таймер:

Код:

$hgui = GUICreate("111", 500, 300, -1, -1)

$s1 = GUICtrlCreateButton('Start', 100, 10, 50, 22, 0x0)
$s2 = GUICtrlCreateButton('Stop', 100, 50, 50, 22, 0x0)

GUISetState()

While 1
    Switch GUIGetMsg()
        Case -3, $s2
            Exit
        Case $s1
            For $i = 1 To 5
                MsgBox(0, '222', '333', 1)

                $iTimer = TimerInit()

                While TimerDiff($iTimer) < 3000
                    Switch GUIGetMsg()
                        Case -3, $s2
                            Exit
                    EndSwitch
                WEnd
            Next
    EndSwitch
WEnd


Атос 28-07-2017 10:21 2754591

Creat0R, а как можно сделать более универсальное решение?
Дело в том, что там не MsgBox, а абсолютно разные и непредсказуемые команды.
Много долгих Sleep.
Как можно сделать такую кнопку, при нажатии на корторую, будет немедленно выход из цикла, или из скрипта?

Creat0R 28-07-2017 16:35 2754644

Цитата:

Цитата Атос
Много долгих Sleep. »

Которые нужно заменить на циклы, либо создать функцию чтобы не повторять:

Код:

#include <GUIConstantsEx.au3>

Global $hGUI, $iStart_Bttn, $iStop_Bttn
Global $iStop_Flag = False

$hGUI = GUICreate("111", 500, 300)

$iStart_Bttn = GUICtrlCreateButton('Start', 100, 10, 50, 22, 0x0)
$iStop_Bttn = GUICtrlCreateButton('Stop', 100, 50, 50, 22, 0x0)

GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $iStart_Bttn
                        _Start()
                Case $iStop_Bttn
                        _Stop()
    EndSwitch
WEnd

Func _Start()
        GUICtrlSetState($iStart_Bttn, $GUI_DISABLE)
        GUICtrlSetState($iStop_Bttn, $GUI_ENABLE)
       
        For $i = 1 To 5
                MsgBox(0, '222', '333', 1)
                _Sleep(3000)
               
                ;MsgBox(0, '444', '555', 1)
                ;_Sleep(5000)
               
                ;MsgBox(0, '666', '777', 1)
                ;_Sleep(8000)
               
               
                ;SHOULD BE AT THE END
                If $iStop_Flag Then
                        ExitLoop
                EndIf
        Next
       
        _Stop()
EndFunc

Func _Stop()
        $iStop_Flag = False
       
        GUICtrlSetState($iStart_Bttn, $GUI_ENABLE)
        GUICtrlSetState($iStop_Bttn, $GUI_DISABLE)
EndFunc

Func _Sleep($iTime)
        If $iStop_Flag Then
                Return
        EndIf
       
        Local $iTimer = TimerInit()
       
        While TimerDiff($iTimer) < $iTime
                Switch GUIGetMsg()
                        Case $iStop_Bttn
                                $iStop_Flag = True
                                ExitLoop
                        Case $GUI_EVENT_CLOSE
                                Exit
                EndSwitch
        WEnd
EndFunc

В любом случае Sleep будет останавливать выполнение скрипта.
Тут нужно либо повесить всё выполнение кнопки на внешний скрипт, либо постоянно проверять событие нажатия кнопки выхода/завершения, как я это сделал выше в примерах.

Mike909 29-07-2017 09:57 2754742

Вот получился рабочий код, с добавлением таймера и своей обработки событий :

Код:

#include <GUIConstantsEx.au3>
Opt("GUIOnEventMode", 1)

$hgui = GUICreate("111", 500, 300, -1, -1)
Local $s1 = GUICtrlCreateButton('Start', 100, 10, 50, 22, 0x0)
GUICtrlSetOnEvent(-1, 'Start')
Local $s2 = GUICtrlCreateButton('Stop', 100, 50, 50, 22, 0x0)
GUICtrlSetOnEvent(-1, 'Stop')

GUISetOnEvent($GUI_EVENT_CLOSE, 'Stop')

GUISetState()

While 1
    Sleep(10)
WEnd

;
Func Stop()
    Exit
EndFunc

;
Func Start()
    GUICtrlSetState($s1,$GUI_DISABLE)
    AdlibRegister("Timer1", 10) 
EndFunc
Func Timer1()
    For $i = 1 To 5
        MsgBox(0, '222', '333', 1)
        Sleep(3000)
    Next
    GUICtrlSetState($s1,$GUI_ENABLE)
    AdlibUnRegister("Timer1")
EndFunc


Атос 29-07-2017 12:07 2754756

Creat0R, Mike909, спасибо.

Creat0R 31-07-2017 20:07 2755254

Mike909,
Когда в вашем примере произойдёт событие Timer1(), и начнётся цикл For, скрипт остановит своё выполнение пока не закончится Sleep(3000).
Exit сработает, но не оставновка цикла в событий.

Mike909 31-07-2017 20:18 2755257

Creat0R,
Цель, вроде бы, выйти из скрипта. Если бы были вопросы по выходу из цикла, я бы посоветовал сделать булевый маркер и его менять и проверять.
Но раз вопросов не последовало, значит идеи достаточно, и Атос либо сам сделал как ему надо, либо так и надо было.


Время: 20:06.

Время: 20:06.
© OSzone.net 2001-