- Tilcon圖形界面設計基礎
- 易流平等
- 6054字
- 2020-09-15 16:55:44
2.3.1 通知、回調、觸發器與鏈接
要完全理解通知、回調、觸發器和鏈接的功能,首先必須理解界面編輯器操作、GUI引擎和API接口的工作原理,以及三者是如何與應用程序、用戶進行交互的。開發者使用界面編輯器為系統最終用戶設計界面窗口,并定義界面參數,比如設置執行時的通知、回調、觸發器、彈出菜單和鏈接功能,事件發生時,GUI引擎就能理解這些事件,并做出相應的響應。
GUI引擎接收用戶和應用程序傳遞的數據,比如用戶在圖形界面中點擊鼠標、按下按鍵等,GUI引擎理解后,根據用戶設置做出響應。比如發送事件通知給應用程序,應用程序再根據程序代碼執行相應的事件處理以響應通知消息;應用程序也可以主動使用API命令發送界面更新和信息(比如修改儀表數值)給GUI引擎,GUI引擎理解后,再將更新和信息推送到界面顯示給用戶。
在開發階段,開發者可以使用觸發器功能指定用戶與對象的交互產生的響應操作,比如用戶按下指定的按鈕,即顯示指定的窗口,開發者可以在該按鈕上設置一個觸發器,當按鈕在觸發器內被按下,GUI引擎就打開指定的窗口。Tilcon中的觸發器只與GUI引擎和用戶進行交互,而不與應用程序進行交互。
回調是應用程序中與響應特定事件時被調用的函數,比如特定按鈕被按下時可以觸發一次回調。
鏈接功能用于鏈接兩個以上對象,這些對象必須共享和顯示相同的值。應用程序發送數據更新到某個對象時,鏈接到該對象的其他對象也會同步更新。鏈接是從應用程序收集數據,而通知、觸發器和回調都是用于響應用戶動作。
API是Tilcon圖形界面與應用程序之間的交互接口,API庫中包含了大量GUI引擎能夠理解和執行的功能函數和命令,比如與通知和回調有關的API命令是TRT_GetInput()。當通知或回調發生時,GUI引擎將一個事件描述結構體推送到隊列中,然后告知應用程序,并返回到自己的主循環;應用程序執行API命令TRT_GetInput()并等待從通知隊列中接收下一個事件。若該事件為回調,則從TRT_GetInput()函數調用返回之前回調就會被執行,且回調執行返回值為1。
1.通知 在許多窗口和對象的屬性設置對話框中,都有消息通知復選框,如圖2-2所示。

圖2-2 多種對象的通知消息類型
在通知復選框被選中的情況下,當預定義的事件發生時,GUI引擎將通知實時應用程序。應用程序接收到事件通知后,通常需要檢查事件通知結構體中的Code和ID字段,以確定調用哪個回調函數。例如,在一個打開的窗口中,有一個儀表需要更新數據,通過發送通知消息給實時應用系統告知窗口已被打開,GUI引擎將創建更新儀表數據的必要條件。
2.回調 回調是一種用于綁定事件和對象到應用程序的交互機制,也是一種減少通知的ID分析的方式,建立回調過程和在用戶應用程序中處理用戶事件的解析工作都很少。每個對象在使用前都會在GUI引擎上注冊一個或多個回調函數,當匹配的用戶輸入事件發生時,相應的回調函數即被調用。回調機制看上去是GUI引擎在應用程序中調用函數以響應綁定在對象上的用戶事件。由于回調函數是在應用進程中定義,而GUI引擎在另一個不同的進程中,所以必須在應用進程中調用TRT_GetInput()為GUI引擎完成回調。每個進程都有自己的內存印象圖,無法在沒有幫助的情況下訪問另一個進程中的內存或回調函數。
當TRT_GetInput()接口被調用時,GUI引擎將指示API庫當前通知存在一個回調操作,API庫將在返回應用前執行該回調函數。對于一個通知來說,該消息由描述事件的結構體組成,而對于回調來說,該消息還包括回調函數地址。應用程序接收到事件通知消息后,需要檢查通知結構體中的Code和ID,以決定調用哪個回調函數。由于在回調創建過程中,回調通知已經關聯事件到回調函數,因此這個步驟可以通過使用回調來去除。回調函數的觸發條件在界面編輯器中通過對象的回調函數對話框進行設置,這些觸發條件都注冊在TWH表中,并被保存在TWD文件中。TWH表中注冊了函數名(應用中的回調函數)和與之匹配的客戶端數據(應用中的變量名、結構體或長整型數),回調數組名為結構體名后追加callback字符串。TWH文件必須編譯到應用代碼中,應用必須使用TRT_WindowCallbacks()接口調用通過結構體將這些信息傳遞給GUI引擎。
(1)回調設置過程 在界面編輯器中,可以設置回調的對象有可編輯文本、標簽文本、多行文本、按鈕、單選按鈕、復選框、數字框、列表框、組合框(下拉列表框)、樹、滑動塊、目錄框、原生圖、顏色列表框、顏色組合框、LCD文本、Map對象等。為對象建立回調,需要執行如下操作:
1)在窗口屬性設置對話框中,輸入窗口的結構名;
2)在回調函數設置對話框,輸入函數名(必需)和客戶端數據(可選)。
為了更好地理解回調設置過程,示例如下:
打開界面編輯器,在畫布窗口點擊右鍵,彈出窗口屬性設置對話框,在結構體名稱設置項輸入ST_name,如圖2-3所示;

圖2-3 設置窗口結構名
點擊“Close”按鈕,關閉對話框。選擇“File > Save As”菜單或點擊快捷工具欄中的“Save”按鈕,保存當前窗口為callbackTest.twd文件。
在當前窗口中,添加兩個按鈕,并為他們設置表2-1所示回調函數。
表2-1 按鈕回調函數列表

按照表2-1所示信息,分別在按鈕b1和b2的回調函數設置對話框中,輸入如圖2-4所示內容。



圖2-4 按鈕回調函數設置
保存callbackTest.twd文件,并在同級目錄下生成callbackTest.twh文件。用文本編輯器打開callbackTest.twh文件,我們可以看到如下內容:
extern void callb1(TRT_ReceiveData*, void*); extern void callb2(TRT_ReceiveData*, void*); extern void callb3(TRT_ReceiveData*, void*); struct { void (*callback)(TRT_ReceiveData*,void*); void *client_data; } ST_name_callback[8] = { callb1,(void *)&cbdata1,NULL,NULL,NULL,NULL,NULL,NULL, // type: button, ID:b1 callb2,(void *)&cbdata2,callb3,(void *)15,NULL,NULL,NULL,NULL, // type: button, ID:b2 };
callbackTest.twh文件只能在應用代碼中被包含一次,客戶端數據變量必須在該文件被包含之前在應用代碼中聲明。同時,回調函數也必須在應用代碼中調用TRT_WindowCallbacks()向GUI引擎注冊(示例如下)。
main() { long cbdata1=5; char cbdata2[5]="Hi!"; struct { long v1; void *ptr; }cbdata2; #include “callbackTest.twh” /*...*/ TRT_WindowLoad (TRT_pid, “callbackTest”); TRT_WindowCallbacks (TRT_pid, “callbackTest”, ST_name_callbacks, sizeof(ST_name_callback)); /*...*/ } /*Sample callback*/ void callb1 (void * trt_data, void *client_data) { TRT_ReceiveData *rec_data = trt_data; long *lvalue = client_data; printf ("code %d id %s\n", rec_data->code, rec_data->ID); printf ("client_data %d\n",*lvalue); }
當按鈕b1被點擊時,GUI引擎將發送消息通知應用程序調用callb1函數。TRT_ReceiveData結構體是回調函數的第一個參數,客戶端數據變量的地址是回調函數的第二個參數。以上示例代碼將打印如下輸出信息:
code b id b1 client_data 5
(2)回調通用設置 所有界面對象在建立回調時,都需要執行如下所示的一些通用設置:
1〉從下拉框中選擇一個回調條件(可以為每個回調條件設置一個回調);
2〉點擊“Callback Attributes”設置區內的“Enable”或“Disable”選擇框,作為回調的初始狀態(該標識也可以通過Tilcon API調用進行修改);
3〉若需要先前設置的刪除回調,點擊“Delete Callback”按鈕;
4〉輸入回調函數名稱(應用代碼中的函數名);
5〉輸入客戶端數據名稱(應用代碼中的變量、結構體或數值);
6〉點擊“OK”按鈕關閉對話框,并保存當前回調設置;或點擊“Cancel”按鈕,關閉對話框,并放棄當前回調設置。
(3)回調條件 不同類型界面對象有不同的回調條件,各類對象的回調條件如下:
1〉按鈕或復選框:Change to In/On、Change to Out/Off、Gain Focus、Lose Focus;
2〉可編輯文本:On Text if Modified、On Key Stroke、Gain Focus、Lose Focus;
3〉標簽文本:On Key、Gain Focus、Lose Focus;
4〉單選按鈕:Single Click、Gain Focus、Lose Focus;
5〉組合框、列表框、樹、顏色組合框、列表框:Single Click、Double Click、Gain Focus、Lose Focus;
6〉按鈕式菜單:Single Click;
7〉圖表:Gain Focus、Lose Focus;
8〉目錄框:Single Click、Double Click;
9〉圖片、LCD對象:On Click、Gain Focus、Lose Focus;
10〉滑動塊、數字框:On Release、On Change、Gain Focus、Lose Focus;
11〉彈出式菜單:Checked、Unchecked。
3.觸發器 觸發器是內嵌到窗口或對象中的必備API命令,當對象進入預定義狀態時,執行該API命令以觸發一個或多個動作(比如打開一個對話框)。觸發器適用于對象和窗口兩種不同的實體。
(1)對象觸發器 對象觸發器允許針對特定對象觸發一個指定的動作,共有八種可供選擇的觸發器動作:刪除、顯示、隱藏、灰顯、亮顯、特效、修改、賦值。刪除觸發器用于執行滿足事件觸發條件時的刪除操作,比如設置按鈕In/On狀態上的觸發器在按鈕被點擊時,刪除一張圖片。顯示觸發器用于執行滿足顯示事件觸發條件時的對象顯示操作,比如設置按鈕In/On狀態上的觸發器在按鈕被點擊時,顯示一張圖片。隱藏觸發器用于執行隱藏事件觸發時的對象隱藏操作,比如設置按鈕In/On狀態上的觸發器在按鈕被點擊時,隱藏一張圖片。灰顯觸發器用于執行灰顯事件觸發時的對象灰顯操作,比如設置按鈕In/On狀態上的觸發器在按鈕被點擊時,灰顯一張圖片。亮顯觸發器用于執行亮顯事件觸發時的對象亮顯操作,比如設置按鈕In/On狀態上的觸發器在按鈕被點擊時,亮顯一張圖片。特效觸發器用于執行特效事件觸發時的對象特效操作,比如設置按鈕In/On狀態上的觸發器在按鈕被點擊時,特效顯示另一個按鈕對象,改變顯示位置、大小和淡入淡出。修改觸發器用于執行修改事件觸發時的對象屬性修改,比如設置In/On狀態按鈕On狀態的修改觸發器為當按鈕被點擊時,修改繪圖對象(比如圓)的顏色屬性。賦值觸發器用于執行事件觸發時的對象屬性賦值,比如設置In/On狀態按鈕On狀態的賦值觸發器為當按鈕被點擊時,修改按鈕的文本屬性值。
觸發器由界面編輯器創建,狀態對象、可編輯文本和所有GUI/HMI對象(按鈕、菜單項等)都可以觸發事件。狀態對象的每個狀態都可以獨立地觸發事件,若狀態對象被更新(值改變但狀態不改變),則觸發器不會被執行。菜單的每個選項、列表框中的每個選項或簡略按鈕都可單獨觸發事件。
每個按鈕的進入、退出狀態都有自己的觸發器,對象的最終狀態決定執行哪個觸發器,按鈕可以在進入和退出狀態之間切換,或永久性地保持一個狀態,或由撥動開關控制狀態,在創建觸發器之前明確是否允許按鈕進行狀態切換是至關重要的一點。若創建了兩個及以上的觸發器,其中一個觸發器動作是刪除包含該觸發器的窗口,則該觸發器必須是觸發器隊列中的最后一個。在按鈕變更狀態時,觸發器也可以執行。
進行按鈕觸發器配置時,將彈出兩個配置對話框,一個是觸發器配置對話框、另一個是對象配置對話框,如圖2-5所示。


圖2-5 按鈕觸發器配置對話框
在對象配置對話框中,顯示了“Text”“GUI”“Window”“HMI”四個單選按鈕選項標簽,單選按鈕被選中后,將在“Object Type”列表框中顯示對應的可選對象類型,在“Trigger Type”列表框中顯示對象的可選觸發器動作。Text、GUI、HMI對象的可選觸發器動作有刪除、顯示、隱藏、灰顯、亮顯、特效、修改和賦值,Window對象的可選觸發器動作有刪除、顯示、隱藏和加載。“Start Time(ms)”配置項允許開發者以毫秒的精度控制觸發器動作的開始執行時間。“Trigger Object ID Of”配置項列舉了觸發器綁定的對象ID。“ID's List”配置項顯示了當前界面窗口中的可選對象類型。
在觸發器配置對話框中,用戶輸入觸發狀態配置用于創建用戶動作型觸發器,比如鼠標點擊、按鍵操作;值修改觸發狀態配置用于使能/禁用狀態對象,狀態對象的回調條件和值設置后,當回調條件滿足時,動作即被觸發,比如彈出消息窗口、按鈕顏色從綠色變為紅色;觸發器創建列表列舉了當前對象建立的所有觸發器動作,一個觸發器可以觸發一個或多個動作;編輯按鈕用于修改觸發器配置;后置添加按鈕用于在選定的觸發器之后添加另一個觸發器;前置添加按鈕用于在選定的觸發器之前添加另一個觸發器;刪除按鈕用于刪除選定的觸發器;每秒更新次數設置框用于設置每秒觸發器動作執行的頻數;特效顯示速率設置框用于設置觸發器特效執行速率,值越大特效運行的越快,反之亦然。
(2)窗口觸發器 窗口觸發器允許針對特定窗口觸發一個動作,對于那些希望動態創建快速演示程序或無須用戶輸入應用系統的非編程人員來說,這是一個非常有用的特性。
當窗口被選中時,點擊快捷工具欄中的創建動畫圖標,彈出模擬對話框,如圖2-6所示。

圖2-6 模擬對話框
在“Add Trigger”列表框中有四種窗口觸發器動作可供選擇:Delete、Display、Hide、Load。其中,Delete觸發器用于刪除選定的窗口;Display觸發器用于顯示選定的窗口;Hide觸發器用于隱藏選定的窗口;Load觸發器用于加載一個窗口文件到內存中,Load觸發器必須在Display觸發器之前創建。
4.鏈接 鏈接功能用于匹配兩個或多個對象以共享同一的值,比如鏈接消息文本到儀表上,這樣就可以讀取儀表數值到消息文本中,同一信道內的任意多個對象都可以鏈接在一起。鏈接在窗口創建時指定,在界面實時顯示期間無須調用API函數即可實現對象更新或執行動作。例如,對象A、B、C、D在同一信道上,則它們可以彼此相互鏈接、共享、甚至顯示相同的值,在同一鏈接組內的任何對象的值被修改,該鏈接組內的其他對象的值也會同步修改,但該鏈接對其他信道上的對象不可見。被鏈接到同一組的對象擁有相同的鏈接組ID(區分字母大小寫),但用同一鏈接組ID對多個對象賦值并不足以把它們鏈接在一起。為了確保鏈接的正確創建,必須對鏈接中的每個對象進行單獨的顯式鏈接設置。
大多數存儲數值的對象都可以把數值鏈接到其他對象的數值上,表2-2是可鏈接對象與存儲值類型列表。
表2-2 可鏈接對象及其存儲值類型

[注意]任意到圖表Y坐標的鏈接都是單向鏈接,例如當圖表接收到新數據時,鏈接到圖表Y坐標的儀表可以自動更新,但如果數據發送給儀表,圖表則不會更新,這樣鏈接中的每個對象都可以執行各自的數據計算。
我們以兩個對象A和B之間建立鏈接(對象A鏈接到對象B)為例,對象A的鏈接配置對話框如圖2-7所示,配置過程需要執行的主要步驟如下:

圖2-7 對象A的鏈接配置對話框
(1)若要鏈接創建后立即生效,則點擊“Value Change Link State”配置區域內的“Enable”按鈕;若在其他條件滿足時才形成有效鏈接,則點擊“Value Change Link State”配置區內的“Disable”按鈕,初始化鏈接為禁止狀態。
(2)若對象A的輸入由其他被鏈接的對象B來更新,則點擊“User Input Link State”配置區域內的“Enable”按鈕;若對象A的輸入用于更新其他對象且不被其他被鏈接的對象B更新,則點擊“Disable”按鈕。
(3)在“Link To Group”配置區域內的“Link Group ID”輸入框中,輸入鏈接組ID(該ID也是鏈接到該組內的對象B及其他對象的鏈接組ID)。務必確保不要使用對象ID作為鏈接組ID,因為復用ID將導致系統錯誤,同時記住ID是區分字母大小寫的。
(4)點擊“OK”按鈕,完成并保存對象A的鏈接配置。
對象B的鏈接配置對話框如圖2-8所示,配置過程需要執行的主要步驟如下:

圖2-8 對象B的鏈接配置對話框
(1)若對象A在當前窗口中(與對象B同在一個窗口內),則對象A的鏈接組ID將出現在“Link Group ID List”列表中,只需選中該鏈接組ID即可將對象B綁定到該鏈接上;
(2)若對象A不在當前窗口中(與對象B不同在一個窗口內),則在“Link Group ID”輸入框中輸入在對象A中設置的鏈接組ID(記住ID區分字母大小寫);
(3)選擇鏈接的初始狀態是否為使能狀態,以及當前對象的輸入是否用于更新其他對象;
(4)點擊“OK”按鈕,完成并保存對象B的鏈接配置。
這里,以數字框(ID為number1)鏈接到消息文本(ID為text1)為例,其主要操作步驟如下:
(1)在消息文本對象text1的屬性設置對話框“Action”配置頁面中,點擊“Link Object To”按鈕,彈出對象鏈接配置對話框;
(2)在“Link Group ID”輸入框中輸入鏈接組ID(ID為TXT2NO);
(3)設置“Value Change Link State”和“User Input Link State”配置項為“Enable”狀態,然后點擊“OK”按鈕,完成并保存text1的鏈接配置;
(4)在數字框對象number1的屬性設置對話框“Action”配置頁面中,點擊“Link Object To”按鈕,彈出對象鏈接配置對話框;
(5)若“Link Group ID List”列表中存在ID為TXT2NO的鏈接,則選擇該鏈接組,自動將TXT2NO填寫到“Link Group ID”輸入框中,若不存在ID為TXT2NO的鏈接,則直接將TXT2NO填寫到“Link Group ID”輸入框中;
(6)設置“Value Change Link State”和“User Input Link State”配置項為“Enable”狀態,然后點擊“OK”按鈕,完成并保存number1的鏈接配置。
如此,數字框中的任何數據更新都會同步實時更新消息文本,反之亦然。當使用消息文本鏈接到另一個消息文本對象時,則對象之間的數據更新需要使用管道(TRT_ATT_LINK)傳輸,除非數據遮罩是一個數值,比如TRT_ATT_TEXT|TRT_ATT_LINK。
- ANSYS19.0實例詳解
- 剪映專業版(電腦版)視頻剪輯全攻略:音效添加+轉場特效+視頻制作
- Word 2010實戰技巧精粹
- Adobe創意大學Photoshop CS5 產品專家認證標準教材
- Photoshop CC移動UI設計實用教程
- Java EE 6 with GlassFish 3 Application Server
- 用Studio One輕松制作你的短視頻音樂
- AI設計時代:Midjourney實戰應用手冊
- AutoCAD 2019中文版完全自學手冊(標準版)
- 中文版3ds Max 2012基礎培訓教程(第2版)
- 解密AI繪畫與修圖:Stable Diffusion+Photoshop
- JSF 1.2 Components
- OpenSceneGraph 3.0: Beginner's Guide
- Adobe Audition CS6音頻編輯入門與應用
- 中文版Illustrator CS6完全自學教程