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