去年做了一些關(guān)于Matlab GUI的程序,現(xiàn)在又要做相關(guān)的東西,回想起來,當(dāng)時(shí)很多經(jīng)驗(yàn)沒有記錄下來,現(xiàn)在回顧起來始終覺得不爽,所以從現(xiàn)在開始,一定要勤寫記錄。
從簡單的例子說起吧。
創(chuàng)建Matlab GUI界面通常有兩種方式:
1,使用 .m 文件直接動態(tài)添加控件
2. 使用 GUIDE 快速的生成GUI界面
顯然第二種可視化編輯方法算更適合寫大型程序。
一:創(chuàng)建GUI
1.在 .m文件中動態(tài)添加例如
h_main=figure(‘name’,‘a demo of gui design’,‘menubar’,‘none’,…
'numbertitle','off','position',[100 100 300 100]);
h_edit=uicontrol('style','edit','backgroundcolor',[1 1 1],'position',[20 20 50 20],...
'tag','myedit','string','1','horizontalalignment','left');
h_but1=uicontrol('style','pushbutton','position',[20 50 50 20],'string','INC',...
'callback',['v=eval(get(h_edit,''string''));',...
'set(h_edit,''string'',int2str(v+1));']);
h_but2=uicontrol('style','pushbutton','position',[80 50 50 20],'string','DEC',...
'callback',['v=eval(get(h_edit,''string''));','set(h_edit,''string'',int2str(v-1));']);
2.使用GUIDE幫助創(chuàng)建GUI在Command 里面輸入 GUIDE 或者從菜單里面,或者從快捷按鈕均可 進(jìn)入 GUIDE
新建并且保存后,會生成相應(yīng)的fig文件和m文件,在Layout編輯視圖,可以使用如下工具:
Layout Editor:布局編輯器;
Alignment Tool:對齊工具;
Property Inspector:對象屬性觀察器;
Object Browser:對象瀏覽器;
Menu Editor:菜單編輯器。
二:使用控件新建一個(gè)布局(窗口),可以在新窗口中添加如下控件
1.靜態(tài)文本(Static Text) 2.編輯框(Edit Text)控件
3.列表框(Listbox)控件 4.滾動條(Slider)控件
5.按鈕(Push Button)控件 6.開關(guān)按鈕(Toggle Button)控件
7.單選按鈕(Radio Button)控件 8.按鈕組(Button Group)控件
9.檢查框(Check Box)控件 10.列表框(Listbox)控件
11.彈出式菜單(Popup Menu)控件 12.坐標(biāo)軸(Axes)控件
13.面板(Panel)控件
每一個(gè)控件都有自己的屬性常規(guī)屬性有:
一、控件風(fēng)格和外觀
(1)BackgroundColor:設(shè)置控件背景顏色,使用[R G B]或顏色定義。
(2)CData:在控件上顯示的真彩色圖像,使用矩陣表示。
(3)ForegroundColor:文本顏色。
(4)String屬性:控件上的文本,以及列表框和彈出菜單的選項(xiàng)。
(5)Visible:控件是否可見。
二、對象的常規(guī)信息
(1)Enable屬性: 表示此控件的使能狀態(tài),設(shè)置為on”,表示可選,為“off”時(shí)則表示不可選。
(2)Style:控件對象類型。
(3)Tag:控件表示(用戶定義)。
(4)TooltipString屬性:提示信息顯示。當(dāng)鼠標(biāo)指針位于此控件上時(shí),顯示提示信息。
(5)UserData:用戶指定數(shù)據(jù)。
(6)Position:控件對象的尺寸和位置。
(7)Units:設(shè)置控件的位置及大小的單位
(8)有關(guān)字體的屬性,如 FontAngle, FontName等。
三、控件回調(diào)函數(shù)的執(zhí)行
(1)BusyAction:處理回調(diào)函數(shù)的中斷。有兩種選項(xiàng):即Cancel:取消中斷事件,queue:排隊(duì)(默認(rèn)設(shè)置)。
(2)ButtonDownFcn屬性:按鈕按下時(shí)的處理函數(shù)。
(3)CallBack屬性:是連接程序界面整個(gè)程序系統(tǒng)的實(shí)質(zhì)性功能的紐帶。該屬性值應(yīng)該為一個(gè)可以直接求值的字符串,在該對象被選中和改變時(shí),系統(tǒng)將自動地對字符串進(jìn)行求值。
(4)CreateFcn:在對象產(chǎn)生過程中執(zhí)行的回調(diào)函數(shù)。
(5)DeleteFcn:刪除對象過程中執(zhí)行的回調(diào)函數(shù)。
(6)Interruptible屬性:指定當(dāng)前的回調(diào)函數(shù)在執(zhí)行時(shí)是否允許中斷,去執(zhí)行其他的函數(shù)。
四、控件當(dāng)前狀態(tài)信息
(1)ListboxTop:在列表框中顯示的最頂層的字符串的索引。
(2)Max:最大值。
(3)Min:最小值。
(4)Value:控件的當(dāng)前值。
你可以使用屬性編輯器來設(shè)置屬性
三:寫回調(diào)函數(shù) CallBack
每個(gè)控件都有幾種回調(diào)函數(shù),右鍵選中的控件一般會有如下菜單:
然后就可以跳轉(zhuǎn)到相應(yīng)的 Editor中編輯代碼,GUIDE會自動生成 相應(yīng)的函數(shù)體,函數(shù)名,名稱一般是 控件 Tag+ Call類型名 參數(shù)有三個(gè) ( hObject, eventdata, handles)
其中 hObject 為發(fā)生事件的源控件,eventdata為事件數(shù)據(jù)結(jié)構(gòu),handles為傳入的對象句柄
CreateFcn 是在控件對象創(chuàng)建的時(shí)候發(fā)生(一般為初始化樣式,顏色,初始值等)
DeleteFcn 實(shí)在空間對象被清除的時(shí)候發(fā)生
ButtonDownFcn和KeyPressFcn分別為鼠標(biāo)點(diǎn)擊和按鍵事件Callback
CallBack為一般回調(diào)函數(shù),因不同的控件而已異。例如按鈕被按下時(shí)發(fā)生,下拉框改變值時(shí)發(fā)生,sliderbar 拖動時(shí)發(fā)生等等。
四:句柄圖形之間的層次關(guān)系
可以創(chuàng)建 圖形句柄的常見函數(shù)
1.figure函數(shù):創(chuàng)建一個(gè)新的圖形對象。
2.newplot函數(shù):做好開始畫新圖形對象的準(zhǔn)備。
3.a(chǎn)xes函數(shù):創(chuàng)建坐標(biāo)軸圖形對象。
4.line函數(shù):畫線。
5.patch函數(shù):填充多邊形。
6.surface函數(shù):繪制三維曲面。
7.image函數(shù):顯示圖片對象。
8.uicontrol函數(shù):生成用戶控制圖形對象。
9.uimenu函數(shù):生成圖形窗口的菜單中層次菜單與下一級子菜單。
幾個(gè)實(shí)用的小函數(shù):
uigetfile 選擇文件對話框
uiputfile 保存文件對話框
uisetcolor 設(shè)置顏色對話框
fontsetcolor 設(shè)置字體對話框
msgbox 消息框
warndlg 警告框
helpdlg 消息框
不過如果要讓父窗口不可用,你需要使用uiwait來定焦于用戶對話框。
例如:
h=helpdlg('Please press me!','Attention');
uiwait(h);
四:獲取與設(shè)置對象屬性常用函數(shù):gcf函數(shù):獲得當(dāng)前圖形窗口的句柄
gca函數(shù):獲得當(dāng)前坐標(biāo)軸的句柄
gco函數(shù):獲得當(dāng)前對象的句柄
gcbo函數(shù):獲得當(dāng)前正在執(zhí)行調(diào)用的對象的句柄
gcbf函數(shù):獲取包括正在執(zhí)行調(diào)用的對象的圖形句柄
delete函數(shù):刪除句柄所對應(yīng)的圖形對象
findobj函數(shù):查找具有某種屬性的圖形對象
設(shè)置方法:
(1)get函數(shù)返回某些對象屬性的當(dāng)前值。例如:
p=get(obj,'Position');
(2)函數(shù)set改變句柄圖形對象屬性,例如:
set(obj,'Position',vect);
五:函數(shù)調(diào)用
在一個(gè)m文件中,可以定義多個(gè)函數(shù),但是文件名一定要與第一個(gè)函數(shù)(主函數(shù))一致,
該文件中其他函數(shù)則為本文件的私有函數(shù),外部不可訪問(可以通過參數(shù)調(diào)用的方法訪問,下面會描述)。
例如在一個(gè)程序中,創(chuàng)建一個(gè)fig后,會生成這樣一個(gè)m文件:
function varargout =febirdfun(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @febirdfun_OpeningFcn, ...
'gui_OutputFcn', @febirdfun_OutputFcn, ...
'gui_LayoutFcn', [], ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
解析 一下這個(gè)主函數(shù):首先 gui_State是一個(gè)結(jié)構(gòu),指定了figure打開和輸出函數(shù),
開始 gui_CallBack為空,如果輸入?yún)?shù)個(gè)數(shù)不為0,接下來將輸入第一個(gè)參數(shù)傳遞給gui_State.callback。
接下來用交給 gui_mainfcn函數(shù)處理,gui_mainfcn 根據(jù)gui_State和傳入?yún)?shù)
來確定是執(zhí)子函數(shù),還是打開 fig 文件和運(yùn)行 OpeningFcn和OutputFcn。
如過 gui_Callback為空,那么就運(yùn)行打開主窗口fig文件,否則,調(diào)用子函數(shù)
這個(gè)函數(shù)的作用有:
1.當(dāng)輸入不帶參數(shù)的時(shí)候,能夠打開fig文件,并且初始化控件
2.當(dāng)指定需要調(diào)用的函數(shù)名時(shí),可以作為其他控件callback使用 (實(shí)則調(diào)用同文件中的子函數(shù))
例如,在某一個(gè)控件的 callback 里面這樣寫:(febrdfun為主函數(shù))
febirdfun("@push_button_Callback",gcbf,[])
這樣的調(diào)用就可以調(diào)用文件里面的子函數(shù)。
當(dāng)然也可以使用其他文件里面的函數(shù)作為callback,不過那樣的話,數(shù)據(jù)傳遞會麻煩一些。
下面看figure Openning Function
%================================
function Main_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
% 通常在這里面定義自己的數(shù)據(jù)結(jié)構(gòu)例如
s=struct("P1",v1...
"P2",v2);
handles.MyStruct=s;
% 更新handles數(shù)據(jù)結(jié)構(gòu) 非常重要??!
guidata(hObject, handles);
%================================
function varargout = Main_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
這個(gè)函數(shù)是輸出返回值的定義
注意: matlab 中,function 對應(yīng)的 end 可以沒有,但是隨著版本的更新,end將會被要求。
六:數(shù)據(jù)傳遞在matlab GUI程序中進(jìn)行值傳遞我經(jīng)常使用的兩種方法:
1.利用主函數(shù) 的 handles 數(shù)據(jù)結(jié)構(gòu)傳值
例如在某一個(gè)圖像窗口句柄 中有一個(gè)對象 handles(可以定義自己的數(shù)據(jù)結(jié)構(gòu))
那么在一個(gè)子Callback函數(shù)中,可以通過handles傳遞數(shù)據(jù):
function sliderbar1_Callback(hObject,eventdata,handles)
%% eg1
v1=get(hObject,'value');
obj=handles.Text1 %直接定位 Tag 為 Text1的控件
set(obj,'value',v1);
%% eg2
handles.MyStruct.P1=v1; % 更改handles中的數(shù)據(jù)
guidata(hObject,handles); %更新 handles ?。≈匾?br>
end
2.利用控件的 UserData 來傳值
每一個(gè)控件一般都有一個(gè)屬于自己的自定義域,userData,你可以定義這樣一個(gè)域用來保存自己的數(shù)據(jù),例如在定義 timer 的 TimerFcn中
t1=timer('TimerFcn',{@Timer1Fcn},'ErrorFcn',@Timer1ErrorFcn},'Period',1.0,'ExecutionMode','fixedrate');
t1.Userfata=handles.MyStruct;
這里 Timer1Fcn的調(diào)用看似沒有傳入任何參數(shù),實(shí)際上此函數(shù)的定義一定要有至少兩個(gè)參數(shù)
function Timer1Fcn(obj,eventata)
obj.UserData=XXXXX;%可以這樣共享數(shù)據(jù)
end
當(dāng)然Timer定義的時(shí)候允許這樣傳遞一個(gè)參數(shù),當(dāng)然這樣也可以進(jìn)行傳值.
t1=timer('TimerFcn',{@Timer1Fcn,handles},'ErrorFcn',{@Timer1ErroFcnr,handles},'Period',1.0,'ExecutionMode','fixedrate');