微剋多資訊

 找回密碼
 註冊

Login

Login

搜索
回覆 2則 瀏覽 4492篇

[教學] AutoIt GUI 幼幼班第一課 - 建立視窗 與 按鈕

該用戶從未簽到

發表於 2012-10-23 11:19 | 顯示全部樓層 |閱讀模式
本帖最後由 rictirse 於 2012-11-5 23:31 編輯

前面學過 陣列與 基本的開檔 與 function,就已經獲得了AutoIt 的基本功力

接著教各位設計GUI,GUI比較需要個人的想像力,語法只是一個輔助功能

師父引進門,修行看個人。


我們只要很簡單的兩行指令就可以建立出GUI視窗


GUICreate ( "標題" [, 寬度 [, 高度 [, 左方 [, 上方 [, 類型(Style) [, 進階類型(exStyle) [, 主視窗]]]]]]] )[code=autoit]GUICreate("我的第一個GUI") ; 建立一個置中顯示的視窗
GUISetState() ; 顯示GUI視窗 (預設就是顯示)[/code]但這時候就有人會問,為什麼視窗閃一下就消失了

因為程式語言都是條列式執行

執行Line 1 的時候建立視窗

執行Line 2 的時候顯示視窗

接著就沒有任何命令,當然視窗也就結束了

如果要持續讓GUI視窗顯示,當然就需要一個迴圈,讓視窗持續存在
[code=autoit]Dim $WaitTime = 0 ;;;定義計時器預設為0

GUICreate ("我的第一個GUI") ; 建立一個置中顯示的視窗

GUISetState() ; 顯示GUI視窗 (預設就是顯示)

Do
        Sleep (1000);; 等待1秒鐘 (1000ms = 1sec)
        $WaitTime += 1;;計時器+1
Until $WaitTime > 3 ;; 當WaitTime > 3 的時候結束迴圈(結束GUI)[/code]如果要建置永久存在的GUI就需要死循環,再搭配GUIGetMsg 指令獲取GUI內部的事件,就可以做出基本的GUI動作了[code=autoit]#include <GUIConstantsEx.au3>

GUICreate ("我的第一個GUI")

GUISetState ()

While True ;;;;  While = True 這是一個死迴圈 (無限迴圈)
        $msg = GUIGetMsg();; 獲取GUI內部的動作,只要觸發GUI按鍵 不管是 按下滑鼠、調整視窗、按下結束視窗、最小化視窗 都會返回相關訊息

        If $msg = $GUI_EVENT_CLOSE Then ExitLoop;;按下右上角 結束視窗 則 離開迴圈

WEnd ;;; 宣告迴圈結束點[/code]但單有GUI視窗,沒有子控(按鈕等等),這個GUI根本就沒屁用

所以接下來當來是為你的視窗加入一個按鈕 需要用到指令

GUICtrlCreateButton ( "文字", 左方, 上方 [, 寬度 [, 高度 [, 類型(style) [, 進階類型(exStyle)]]]] )[code=autoit]#include <GUIConstantsEx.au3>

GUICreate ("我的第一個GUI")

Opt ("GUICoordMode", 2);; 使用增量座標系統

$Button_1 = GUICtrlCreateButton ( "開啟記事本", 10, 30, 100) ;; 建立第一個子控按鈕 X軸位置 10 Y軸位置 30, 寬度 100

$Button_2 = GUICtrlCreateButton ( "結束", 10, -1)
;; 因為使用增量座標,所以下面的子控 X 軸 10 繼承 按鈕1 的 (X位置10 + 寬度100) 然後 再加上 按鈕二的增量 10 所以絕對座標示 120
;; -1 就是繼承上面的設定

GUISetState ()

While True
        $msg = GUIGetMsg();; 獲取GUI內部的動作,只要觸發GUI按鍵 不管是 按下滑鼠、調整視窗、按下結束視窗、最小化視窗 都會返回相關訊息
        Switch $msg;;; 搭配 Switch 條列式觸發
                Case  $GUI_EVENT_CLOSE ;;按下右上角 結束視窗 則 執行以下動作
                        ExitLoop ;;; 結束迴圈
                Case  $Button_1 ;;按下Button_1 則執行以下動作
                        Run ("Notepad.exe");;執行 記事本
                Case  $Button_2 ;;按下Button_2 則執行以下動作
                        ExitLoop ;;; 結束迴圈
        EndSwitch ;; 使用條列式 Switch 就一定要搭配 EndSwitch 宣告結束
WEnd[/code]也可以用另一種寫法,這種寫法是比較好的GUI寫法,把全部的指令都包成 function,不但容易維護,一目了然之外

不使用 GUIGetMsg 可以減少GUI視窗卡死的困擾,GUIGetMsg 沒寫好GUI視窗反應會很遲鈍,噹噹建議都使用 GUIOnEventMode 來寫GUI
[code=autoit]#include <GUIConstantsEx.au3>
Opt ("GUICoordMode", 2);; 開啟增量座標
Opt ("GUIOnEventMode", 1);; 開啟OnEventMode
;;;OnEvent 函數僅當選項 GUIOnEventMode 設定為 1 時才能被呼叫 - 在此模式下 GUIGetMsg 將完全無效。

GUICreate ("OnEventMode 演示");; 建立GUI視窗

GUISetOnEvent ( $GUI_EVENT_CLOSE, "_CLOSE");; 按下 右上角 CLOSE 會執行 _CLOSE
GUISetOnEvent ( $GUI_EVENT_MINIMIZE, "_MINIMIZE");; 按下 右上角 MINIMIZE 會執行 _MINIMIZE
GUISetOnEvent ( $GUI_EVENT_RESTORE, "_RESTORE");; 按下 右上角 RESTORE 會執行 _RESTORE

GUICtrlCreateButton ( "開啟記事本", 10, 30, 100);; 創立一個開啟記事本子控按鈕
GUICtrlSetOnEvent ( -1, "_RunNotepad") ;;; 設置 按下 開啟記事本後執行 的 function  , 其中的 -1 代表繼承上面的子控 就不需要 在宣告 子控的變數

                ;;; $NotepadBTN = GUICtrlCreateButton ( "開啟記事本", 10, 30, 100)
                ;;; GUICtrlSetOnEvent ( $NotepadBTN, "_RunNotepad") ;;; 這種寫法也是可以,但是要在宣告一個變數比較麻煩,還會多吃一些記憶體

GUICtrlCreateButton  ("Exit", 10, -1);; 創立一個 Exit子控按鈕
GUICtrlSetOnEvent ( -1, "_Exit");;; 設置 按下 Exit 後執行 的 function

GUISetState (@SW_SHOW);; 顯示GUI

While True;; 無窮迴圈
        Sleep(10);等待 10ms 減少CPU 使用
WEnd

Func _CLOSE()
        MsgBox (0,"","按下了CLOSE")
EndFunc

Func _MINIMIZE()
        MsgBox (0,"","按下了MINIMIZE")
EndFunc

Func _RESTORE()
        MsgBox (0,"","按下了RESTORE")
EndFunc

Func _RunNotepad()
        Run ("Notepad.exe")
EndFunc

Func _Exit()
        MsgBox (0,"","按下了Exit")
        Exit
EndFunc[/code]

該用戶從未簽到

 樓主| 發表於 2013-2-10 14:24 | 顯示全部樓層
上面講完GUI與子控的入門,其他的子控代碼大同小異
參考官方的說明檔就可以深入了解了
接下來教學 Array 搭配 子控時怎麼使用

[code=autoit]#include <GUIConstantsEx.au3>

Const $cnt = 5; 宣告五個子控
Dim $Button[$cnt],$Input[$cnt];宣告 Button與 Input 陣列數量 由 cnt 數量控制
Dim $ButtonText[$cnt] = [ "AAA", "BBB", "CCC", "DDD", "EEE"] ; 按鈕名稱初始化
Dim $x  = 50;定義X 初始位置 50
Dim $y[$cnt] = [ 10, 50, 90, 130, 170]; 分別定義五個 Y軸 位置
Dim $Width[$cnt] = [ 100, 100, 100, 100, 100]; 分別定義五個 子控寬度
Dim $Height[$cnt] = [ 30, 30, 30, 30, 30] ; 分別定義五個 子控高度

GUICreate ( "子控 搭配 Array", @DesktopWidth/2,@DesktopHeight/2)

For $i=0 to $cnt-1;; 宣告 for loop ; i = 0→cnt-1
        $Input[$i] = GUICtrlCreateInput ( "第 "&$i&" 子控", $x, $y[$i], $Width[$i], $Height[$i]);宣告 Input 子控 X、Y、W、H 都由上面宣告的陣列控制
        $Button[$i] = GUICtrlCreateButton ( $ButtonText[$i], $x+$Width[$i]+20, $y[$i], $width[$i], $height[$i]);宣告 Button 子控 X、Y、W、H 都由上面宣告的陣列控制
Next ;; 結束for loop

GUISetState();; 顯示GUI
While 1
        $msg = GUIGetMsg ()

        For $i=0 to $cnt-1;; 宣告 for loop ; i = 0→cnt-1
                If $msg = $Button[$i] Then MsgBox (0,"", "按下了"&$ButtonText[$i])
                ;;; if GUIGetMsg 抓到視窗內的動作 是在 按下Button[$i] 時 跳出msg 視窗
        Next

        If $msg = $GUI_EVENT_CLOSE Then Exit
Wend
[/code]

本帖子中包含更多資源

您需要 登入 才可以下載或查看,沒有帳號?註冊

x
回覆

使用道具 舉報

該用戶從未簽到

 樓主| 發表於 2013-2-10 14:25 | 顯示全部樓層
接著教動態生成GUI,這算是比較深入的用法

[code=autoit]#include <GUIConstantsEx.au3>
#include <Array.au3>

Opt ( "GUIResizeMode", $GUI_DOCKMENUBAR)

; for edit box

; editbox param
Global $X0 = 10
Global $Y0 = 20
Global $H  = 20
Global $W  = 100
Global $DISTANCE = 10

;Initialize variables
Dim $GUIWidth = 300, $GUIHeight = 250
Dim $new_Btn, $msg

Dim $editbox_cnt = 1
Dim $EditBox[$editbox_cnt]
Dim $EditBoxTmp
        ;Create window
$gui = GUICreate ("New GUI", $GUIWidth, $GUIHeight)
        ;Create an "$new_Btn" button
$new_Btn = GUICtrlCreateButton ( "New BTN", 200,20,70,25)
$del_Btn = GUICtrlCreateButton ( "Del BTN", 200,50,70,25)
$getmsg  = GUICtrlCreateButton ( "GetMsg", 200,80,70,25)

;Create an "EditBox"
$EditBox[$editbox_cnt-1] = GUICtrlCreateInput ( $editbox_cnt-1, $X0, $Y0, $W, $H)
$Y0 = $Y0 + $H  + $DISTANCE;計算出第二個 Y座標

;Show window/Make the window visible
GUISetState(@SW_SHOW)
        ;Loop until:
While 1
        ;After every loop check if the user clicked something in the GUI window
        $msg = GUIGetMsg()
        Select
                ;Check if user clicked on the close button
                Case $msg = $GUI_EVENT_CLOSE
                        ;Destroy the GUI including the controls
                        GUIDelete()
                        Exit
                        ;Check if user clicked on the "OK" button
                Case $msg = $new_Btn
                        ;Create an "EditBox"
                        $editbox_cnt += 1
                        ReDim $EditBox[$editbox_cnt]
                        $EditBox[$editbox_cnt-1] = GUICtrlCreateInput ( $editbox_cnt-1, $X0, $Y0, $W, $H)
                        $Y0 = $Y0 + $H  + $DISTANCE
                        If $GUIHeight < ($Y0) Then
                                WinMove ( $gui, "", Default,Default ,$GUIWidth+6, $Y0+43)
                        EndIf
                case $msg = $del_Btn
                        If  $editbox_cnt > 1 Then
                                GUICtrlDelete ( $EditBox[$editbox_cnt-1] )
                                $editbox_cnt -= 1
                                ReDim $EditBox[$editbox_cnt]
                                $Y0 = $Y0 - $H  - $DISTANCE
                                If $GUIHeight < ($Y0) Then
                                        WinMove ( $gui, "", Default,Default ,$GUIWidth+6, $Y0+43)
                                EndIf
                        EndIf
                case $msg = $getmsg
                        Dim $Gmsg = ""
                        For $i = 0 To ($editbox_cnt-1)
                                $Gmsg = $Gmsg&GUICtrlRead ($EditBox[$i])&@CRLF
                        Next
                        MsgBox ( 0, "", $Gmsg, 1)
        EndSelect
Wend
[/code]

本帖子中包含更多資源

您需要 登入 才可以下載或查看,沒有帳號?註冊

x
回覆

使用道具 舉報

您需要登入後才可以回帖 登入 | 註冊

本版積分規則

小黑屋|Archiver|微剋多資訊(MicroDuo)

GMT+8, 2016-12-9 13:47

Discuz! X

© 2009-2016 Microduo

快速回覆 返回頂部 返回列表