Matlab的GUI參數傳遞方式總結

MATLAB GUI傳遞方式

一、全局變量;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自己的varain{}、varaout{}傳遞參數

這種方式僅適用於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數據

直接經過對象的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。

四. GUI數據(handles)

結合handles和guidata函數,適用於gui內,若是你在pushbutton1中獲得一個變量X,相傳出去,那麼在pushbutton1的callback中,在獲得X後添加以下代碼:

     handles.X=X;

     guidata(hObject,handles)(注意,必定是兩行連寫)

 在pushbutton2中要用到X是,在其callback先添加  X=handles.X; 便可獲得X的值。

注:

  1. guidata(object_handle,data);若是object_handle不是figure型句柄,那麼會將data保存在object_handle的父figure對象中。這樣沒必要擔憂在一個pushbutton的callback中存儲的變量在其餘對象中沒法提取。
  2.  data = guidata(object_handle);獲取當前object_handle的handles數據,最後一次guidata(object_handle,data)保存的數據。

一個簡單的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)

五. Application數據

應用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)

六. 跨空間計算evalin和賦值assignin

適用於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的M文件

這個相信你們都很熟悉了,適用於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

相關文章
相關標籤/搜索