12/31/2006

自製GUI介面

前面介紹使用GUIDE函數組合GUI介面,雖然方便,但是必須同時保留兩個檔案(即.fig與.m檔案)才能執行,應用上比較麻煩。撰寫GUI介面程式也可以不經GUIDE函數的環境而獲得同樣的目的。下面就介紹以純程式撰寫之角度完成相同介面之寫作方法。

開始時,先產生一個基本的M-檔案,以代替GUIDE之圖形編輯介面:

在 MATLAB 指令窗下,打入


edit simple_gui2

此時,MATLAB 之編輯器會打開,並產生一個新檔simple_gui2.m。 在編輯器中打入第一行程式,作為函數之開頭。


function simple_gui

其次可以加入一些說明行,以作為函數之開場白,最後加一空白行,使打入help simple_gui2指令後,能出現空白行所以上所列之說明文字:


% SIMPLE_GUI Select a data set from the pop-up menu, then
% click one of the plot-type push buttons. Clicking the button
% plots the selected data in the axes.
(留下至少一空白行)


在程式之最後,應加上一個end,因為在後來之回收函數加入時係以巢狀函數之型式出現,此時之主函數必須加上end之指令,以區別主函數之限界。即程式應為:


function simple_gui2
% SIMPLE_GUI Select a data set from the pop-up menu, then
% click one of the plot-type push buttons. Clicking the button
% plots the selected data in the axes.
(留下至少一空白行)

end


Figure指令之運用

在 MATLAB中,一個 GUI介面本身也是一張圖。因此,首要之步驟是在螢幕的一角落上定位出所需之繪圖位置及其大小。這項工作通常可藉助figure這個指令來達成。前面第九章中曾介紹此一指令之應用,大體上都是用來指示所要繪圖之圖序,以決定在眾圖中指令所要引用或加添的圖號,如figure(2)是。但是,此一指令也有較複雜的用法,諸如設定圖的名稱或其參數,如:


figure('Name','Simulation Plot Window','NumberTitle','off')

這個指令是開啟一個圖版,將其序號隱去,此圖檔之名稱為'Simulation Plot Window',此圖名使用中文亦可,若序號不設成'off',則圖號會與圖名同時出現。這裡所定的圖視窗是以Matlab之預設參數為之,是以仍有相關的指令目錄可以使用。

這個圖指令之另一項功能是用來自行定介面圖視窗之位置與大小。也可以預設該圖是否在元件加入過程是否為可見。若'Visible'設定為'off',表示使用者無法看到元件之加入與初始化之過程。其程式型式如下:


% Initialize and hide the GUI as it is being constructed.
f = figure('Visible','off','Position',[360,500,450,285]);

在呼叫圖視窗時,其所需輸入之參數通常成對輸入,即屬性與屬性值。後者可用字串、陣列或數值等,依其特性而定。在視窗位置以'Position'表示,其對應值為一陣列,其位置與左邊界及底邊界之距離、寬度與高度。例如,[360,500,450,285]表示離左邊界為360單位、離底邊界為500單位,而寬度與高度分別為450與285個單位。其單位可為像數值或字數,必須在屬性表中設定,否則其預設值為像素。


如何加入元件


在本例之 GUI介面中具有六項元件,即三個按鈕、一靜態文字、一跳出式選單及一個圖軸。現在就針對這六項開始寫入元件之程式。前五項可用uicontrol指令建立;圖形則必須利用軸指令 axes 函數產生座標軸。

在figure指令執行後,即可加入三行uicontrol指令,以設定三個按鈕之 GUI ,以函數之呼叫形式存在M-檔案之中:

% Construct the components.
hsurf = uicontrol('Style','pushbutton',...
'String','Surf','Position',[315,220,70,25]);
hmesh = uicontrol('Style','pushbutton',...
'String','Mesh','Position',[315,180,70,25]);
hcontour = uicontrol('Style','pushbutton',...
'String','Countour','Position',[315,135,70,25]);

使用uicontrol指令主要在取代前面guide的功能,可以由程式設計者決定元件之屬性,取代guide的屬性表。利用uicontrol指令設定按鈕之參數時,仍然採用{屬性/數值}之配對輸入方式,列項於uicontrol函數之參數之中。目前比較常用之屬性參數如下表:


屬性
功能說明
Style
本例中, pushbutton 表示按鈕元件;popupmenu表示跳出式選單。
String
內含顯示在按鈕上之標示文字,此例中有三種繪圖標示,即 Surf, Mesh, Contour等。
Position
採用四元素陣列表示每個按鈕之位置與大小,分別[至左邊界之距離 至底邊界之距離,寬度,高度],其預設單位為像素。



每次呼叫uicontrol函數後均會產生一個對應握把,作為分辨元件呼叫之基礎,此處將三個按鈕元件分別設定為hsurf、hmesh、 hcontour。

其次再處理跳出式選單及靜態文字兩元件,此時仍然以同同樣的指令,但設定不同的'Style',其屬性值分別為'popupmenu'與'text',所得的握把分別設為hpopup與htext',注意這兩元件同樣均需設定個別之'Position'參數,其屬性值則會不一樣:

hpopup = uicontrol('Style','popupmenu',...
'String',{'Peaks','Membrane','Sinc'},...
'Position',[300,50,100,25]);
htext = uicontrol('Style','text','String','Select Data',...
'Position',[325,90,60,15]);


在此例中,跳出式選單中之字串屬性String 須使用細胞陣列,分別表示三項目: Peaks, Membrane, Sinc,並且以大括符括起來,表示屬於細胞陣列。本例所用之靜態文字係在說明跳出式選單之內容,設其為Select Data,如此當開始執行時,由String 屬性告訴GUI 介面使用者,由底下之選單中先選擇資料。同樣此處之定位單位仍預設為像素。

圖軸之設定指令不是使用unicontrol 指令而是改用axes指令,其尺寸單位亦應指名相同的單位,以免座標軸顯示之間距產生不對檔的現象。


ha = axes('Units','pixels','Position',[50,60,200,185]);

上述宣告圖軸之握把為ha。除圖軸部份外,將其他元件均居中,則指令敘述可作如下宣告,注意所有要居中之項目之握把可以安排為一個陣列:

align([hsurf,hmesh,hcontour,htext,hpopup],'Center','None');

由於在執行上述變化過程中,不擬讓使用者看到,故曾宣告'Visible''off',現在事情辦妥後可以再宣告為'on',以免什麼都看不到。

set(f,'Visible','on')

最後整個程式內容如下:

function simple_gui2
% SIMPLE_GUI Select a data set from the pop-up menu, then
% click one of the plot-type push buttons. Clicking the button
% plots the selected data in the axes.

% Create and hide the GUI as it is being constructed.
f = figure('Visible','off','Position',[360,500,450,285]);

% Construct the components.
hsurf = uicontrol('Style','pushbutton','String','Surf',...
'Position',[315,220,70,25]);
hmesh = uicontrol('Style','pushbutton','String','Mesh',...
'Position',[315,180,70,25]);
hcontour = uicontrol('Style','pushbutton',...
'String','Countour',...
'Position',[315,135,70,25]);
htext = uicontrol('Style','text','String','Select Data',...
'Position',[325,90,60,15]);
hpopup = uicontrol('Style','popupmenu',...
'String',{'Peaks','Membrane','Sinc'},...
'Position',[300,50,100,25]);
ha = axes('Units','Pixels','Position',[50,60,200,185]);
align([hsurf,hmesh,hcontour,htext,hpopup],'Center','None');

%Make the GUI visible.
set(f,'Visible','on')

end

在指令窗中,可以直接下令執行simple_gui2,其結果如下圖。只是不要高興太早,因為即使你選了項目,且按了鍵,仍然毫無反應。可以想像得到,這是因為我們尚未寫到跳出式視選單之對應程式尚未加入之故。


(編譯及圖示摘自mathworks.com)

如果有空,可以打入 help simple_gui,看看顯示出來之結果如何:

>>help simple_gui
SIMPLE_GUI Select a data set from the pop-up menu, then
click one of the plot-type push buttons. Clicking the button
plots the selected data in the axes.