一、全局變量;html
二、做爲函數的參數傳遞;express
三、利用控件的userdata數據;數組
四、爲handles結構體添加新字段;app
五、setappdata函數爲句柄添加數據;函數
六、跨空間計算evalin和賦值assignin;ui
七、將數據保存到文件,須要時讀取;spa
八、帶參數調用GUI的M文件;orm
九、嵌套函數(不適用於GUIDE中,只適用純命令是的GUI)。htm
運用global定義全局變量傳遞參數,適用於gui內控件間以及不一樣gui間。這種方式恐怕是最簡單的方式,是很省心!可是,簡單的問題就在於有時你會很頭疼!由於在每個要到該全局變量的地方,你都要添一句gloal x,還有就是若是你在一個地方修改了 x的值,那麼全部x的值就都變了!有的時候恐怕會出現紊亂。另外一個更重要的問題在於,套用C++的一句話,全局變量破壞了程序的封裝性!因此,全局變量是能少用盡可能少用。對象
如下創造一個簡單的GUI給你們說明一下,建一個GUI, 包含兩個按鈕,一個座標系,一個用來畫y=sin(x),一個用來畫y=cos(x);
eg:在GUI的OpeningFcn函數中寫:
global x y1 y2
x=0:.1:2*pi;y1=sin(x);y2=cos(x);
在pushbutton1_Callback函數中寫
Global x y1
Plot(x,y1)
在pushbutton1_Callback函數中寫
Global x y2
Plot(x,y2)
全局變量是比較方便的,但全局變量會破壞封閉性,若是不是有大量數據要傳遞,建議不要使用。
這種方式僅適用於gui間傳遞數據,且只適合與主子結構,及從主gui調用子gui,而後關掉子gui,而不適合遞進結構,即一步一步實現的方式。
輸入參數傳遞(主要在子gui中設置):
好比子GUI的名稱爲subGUI, 設想的參數輸入輸出爲:[out1, out2] = subGUI(in1, in2)
在subGUI的m文件中(由GUIDE自動產生):
1.第一行的形式爲:function varargout = subGUI(varargin)
該行不用作任何修改;varargin 和 varargout 分別是一個可變長度的cell型數組。輸入參數in1和in2保存在varargin中,輸出參數out1,out2包含在varargout中;
2.在subGUI的OpeningFcn中,讀入參數,並用guidata保存,即:
handles.in1 = varargin{1};
handles.in2 = varargin{2};
guidata(hObject, handles);
返回參數的設置:
1. 在主GUI的OpeningFcn函數中加上[out1, out2] = subGUI(in1, in2),用於調用子gui,並在結尾加上uiwait(handles.figure1); figure1是subGUI的Tag,主要是等待調用子gui的過程,從而得到子gui的輸出參數out一、out2;
2. subGUI中控制程序結束(如"OK」和"Cancel"按鈕)的callback末尾加上uiresume(handles.figure1),注意是主gui的窗口handles.figure1,不要將delete命令放在這些callback中;
3. 在子GUI的OutputFcn中設置要傳遞出去的參數,如 varargout{1} = handles.out1;varargout{2} = handles.out2;末尾添加 delete(handles.figure1); 結束程序。
在GUI的OpenFcn中,若是不加uiwait, 程序會直接運行到下面,執行OutputFcn。也就是說程序一運行,返回值就肯定了,再在其它部分對handles.output做更改也沒有效果了。
加上uiwait後,只有執行了uiresume後,纔會繼續執行到OutputFcn,在此以前用戶有充分的時間設置返回值。
經過以上設置之後,就能夠經過 [out1, out2] = subGUI(in1, in2) 的形式調用該子程序。
在一個GUI中調用另外一個GUI時,主GUI不須要特別的設置,同調用普通的函數同樣。在打開子GUI界面的同時,主程序還能夠響應其它的控件。不須要擔憂子GUI的返回值被傳錯了地方。
直接經過對象的userdata屬性進行各個callback之間的數據存取操做,主要適用於gui內。首先必須將數據存儲到一個特定的對象中,假設對象的句柄值爲ui_handle,須要存儲的值爲value,則輸入如下程序便可:
set('ui_handle','UserData',Value);
此時,value數據就存在句柄值爲ui_handle的對象內,在執行的過程當中若要取回變量能夠經過如下方式在任意callback中獲取該數據值 :
value=get('ui_handle','UserData');
雖然使用這種方法簡單 ,可是每一個對象僅能存取一個變量值,所以當同一對象存儲兩次變量時 ,先前的變量值就會被覆蓋掉,所以都用UserData存儲簡單與單一的數據。以下面有兩個gui函數, myloadfn加載mydata.mat文件,該文件內存儲XYData變量,其值爲m*2的繪圖矩陣,加載後將該變量值存儲到 當前的窗口的UserData屬性中。另外一個myplotfcn函數則是用以獲取該UserData屬性中存取的繪圖數據,而後繪圖。代碼以下:
function myloadfcn
load mydata;
set(gcbf,'UserData',XYdata)
function myplotfcn
XYdata=get(gcbf,'UserData');
x=XYData(:,1);
y=XYData(:,2);
plot(x,y);
userdata的缺點就是一個句柄只能放一個Userdata。
結合handles和guidata函數,適用於gui內,若是你在pushbutton1中獲得一個變量X,相傳出去,那麼在pushbutton1的callback中,在獲得X後添加以下代碼:
handles.X=X;
guidata(hObject,handles)(注意,必定是兩行連寫)
在pushbutton2中要用到X是,在其callback先添加 X=handles.X; 便可獲得X的值。
注:
一個簡單的GUI給你們說明一下,建一個GUI, 包含兩個按鈕,一個座標系,一個用來畫y=sin(x),一個用來畫y=cos(x);
eg:在GUI的OpeningFcn函數中寫:
x=0:.1:2*pi;
y1=sin(x);
y2=cos(x);
handles.x=x;
handles.y1=y1;
handles.y2=y2;
guidata(hObject, handles);%注意,在OpeningFcn函數中這句是自己存在的,若在其它函數中,務必加上這句
在pushbutton1_Callback函數中寫
x=handles.x;
y1=handles.y1;
plot(x,y1)
在pushbutton2_Callback函數中寫
x=handles.x;
y2=handles.y2;
plot(x,y2)
應用setappdata\getappdata與rmappdata函數,適用於gui間和gui內。使用上面三個函數最有彈性處理數據的傳送問題,與UserData的方式相相似,可是克服UserData的缺點,使一個對象能存取多個變量值。
(1)getappdata函數
value=getappdata(h,name)
(2)setappdata函數
setappdata(h,name,value)
(3)rmappdata函數
rmappdata(h,name)
首先在matlab命令窗口輸入magic(3)數據,所以當前的工做空間就存儲了magic(3)這組數據了,而後創建一個按鈕來獲取並顯示magic(3)數據。
A=magic(3);
setappdata(gcf,'A',A);%save
uicontrol('String','顯示矩陣A','callback','A=getappdata(gcf,''A'')');
A =
8 1 6
3 5 7
4 9 2
當在主、子gui內調用時,能夠以下設置
fig1調用fig2時,使用fig2指令來打開fig2,
在fig2的m文件中,在回調函數中用setappdata(fig1,'A',A);實現返回fig1,並將參數A傳遞給fig1
而後在fig1的使用A的地方添加A=getappdata(fig1,‘A’)。
但這種方式的一個問題就是每調用一次,fig1的數據就得初始化一次,這是由於setappdata(fig1,'A',A)中出現了fig1,調用一次setappdata就得運行一次fig1的緣故,解決方案就是把setappdata(fig1,'A',A)改成setappdata(0,'A',A),這樣把A讀入matlab workspace,至關於一個全局變量了,但固然比直接用global定義全局變量好!
一樣的例子:
eg:在GUI的OpeningFcn函數中寫:
x=0:.1:2*pi;
y1=sin(x);
y2=cos(x);
setappdata(handles.figure1,'x',x) %在figure1下建立’x’,包含數據x,也能夠放在其它句柄下,如setappdata(handles. pushbutton1,'x',x),不過通常放在figure1下,記起來方便……
setappdata(handles.figure1,'y1',y1)
setappdata(handles.figure1,'y2',y2)
在pushbutton1_Callback函數中寫
x=getappdata(handles.figure1,'x');%提取,固然用get了……
y1=getappdata(handles.figure1,'y1');
plot(x,y1)
在pushbutton1_Callback函數中寫
x=getappdata(handles.figure1,'x');
y2=getappdata(handles.figure1,'y2');
plot(x,y2)
適用於gui間和gui內
Assignin函數基本語法
assignin(ws, 'var', val)
其中'base' or 'caller',分別表示基本工做空間和調用函數(caller function)工做空間,
Assinin函數將值val指定給工做空間ws中的變量var,若變量var不存在,則建立一個變量var。
從一個函數function向MATLAB工做空間中輸入數據;
在一個函數function內部,須要改變一個在caller function函數工做空間中定義的變量,例如函數形參列表中的變量。
例子:
%向基本工做空間中傳輸數據變量
Function assignin_test1
prompt = {'Enter image name:','Enter colormap name:'};
title = 'Image display - assignin example';
lines = 1;
def = {'my_image','hsv'};
answer = inputdlg(prompt,title,lines,def);
assignin('base','imfile',answer{1});
assignin('base','cmap',answer{2});
evalin函數基本語法
evalin(ws, expression)
[a1, a2, a3, ...] = evalin(ws, expression)
在特定的工做空間執行MATLAB語句,expression的形式如
expression = [string1, int2str(var), string2,...]
[a1, a2, a3, ...] = evalin(ws, expression),將返回值賦予變量a1,a2,a3,... evalin(ws,'[a1, a2, a3, ...] = function(var)')
注:
evalin('caller', expression),只能指定callerfunction函數中的變量爲expression的語句,而不能是subfunction
該函數不可嵌套使用,evalin('caller', 'evalin(''caller'', ''x'')')是錯誤的
例子:
若是在figure1中有個變量a1
則傳入時assignin('base','data',a1) %data是workplace中的變量
在figure2傳出時a2=evalin('base','data'); %a2是figure2中的變量
運用save和load(importdata)傳遞參數,適用於gui間和gui內。將某變量x的值先存到磁盤,用的時候在調用。格式以下:save('*.mat','x');用的時候就用load('*.mat'),但這樣只是把x讀到了matlab workspace,不會用顯示,你還要再去查看這個變量名, 而後才能用,建議使用p=importdata('*.mat'),p是一個結構體,能夠隨意使用了。固然,這種方式涉及到磁盤讀寫,速度固然會有影響的,通常狀況不用,一般用在保存以及導入某個變量時!
這個相信你們都很熟悉了,適用於gui間和gui內。
① 若是變量數據量很大,須要佔用大量內存,不要將變量存儲爲handles的變量,由於每一個控件每次調用callback function都會使用handles,增長沒必要要的內存開銷。若改變量存取不頻繁,能夠考慮UserData數據或者Application數據;若存取比較頻繁,建議使用Global變量和Application結構體,這裏的Application要定義爲setappdata(0,'var',val)以及getappdata(0,'var',val)。
② 對於GUI界面之間的數據傳遞,能夠考慮如下幾種方法:
方法1:採用global函數。
能夠採用這種方法共享數據;
方法2:採用findobj和findall函數查找對象句柄
findall(0, 'Type', 'figure', 'Tag', 'figure1')
查找標籤爲figure1的窗口,不管該窗口是否隱藏。
方法3:採用handles結構。
假設咱們在窗口1的Opening函數中,採用函數建立了一個子窗口2:
h_fig = figure('Visible', 'off', ...);
h_btn1 = uicontrol('Parent', h_fig, ‘Tag', 'btn1', ...);
h_btn2 = uicontrol('Parent', h_fig, ‘Tag', 'btn2', ...);
h_btn3 = uicontrol('Parent', h_fig, ‘Tag', 'btn3', ...);
若是咱們要在窗口1的任何回調函數中,直接訪問子窗口2的任意控件,能夠在上述語句後緊跟着寫下以下語句:
handles.btn1 = h_btn1;
handles.btn2 = h_btn2;
handles.btn3 = h_btn3;
最後,須要一個guidata語句。固然,Opening函數最後有guidata語句,因此不用本身添加。
方法4:將要共享的數據使用save函數存入mat文件;或者使用文件I/O函數,存入文本文件中。
引用:http://wenku.baidu.com/view/e3b07f624431b90d6d85c71b.html?re=view