matlab GUI如何實現參數傳遞

Matlab的GUI參數傳遞方式

總結別人的帶自己的一些見解,請指正!
matlab gui共有六種參數傳遞方式和範圍各不相同。



        1。運用gui本身的varain{}、varaout{}傳遞參數(注:這種方式僅適用與gui間傳遞數據,且只適合與主子結構,及從主gui調用子gui,然後關掉子gui,而不適合遞進結構,即 一步一步實現的方式)

              輸入參數傳遞:
比如子GUI的名稱爲subGUI, 設想的參數輸入輸出爲:[out1, out2] = subGUI(in1, in2)
在subGUI的m文件中(由GUIDE自動產生):
1.第一行的形式爲:function varargout = subGUI(varargin)
該行不用做任何修改;varargin 和 varargout 分別是一個可變長度的cell數組(MATLAB幫助文件中有說明)。輸入參數in1和 in2保存在varargin中,輸出參數out1,out2 包含在varargout中;
2.在subGUI的OpeningFcn中,讀入參數,並用guidata保存,即:
handles.in1 = varargin{1};
handles.in2 = varargin{2};
guidata(hObject, handles);
返回參數的設置
1. 在GUI子程序的OpeningFcn函數的結尾加上uiwait(handles.figure1); figure1是subGUI的Tag;
2. subGUI中控制程序結束(如"OK”和"Cancel"按鈕)的 callback末尾加上uiresume(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的返回值被傳錯了地方。

        2. 運用global定義全局變量傳遞參數(適用於gui內控件間以及不同gui間)

          這種方式恐怕是最簡單的方式,是很省心!但是但是,簡單的問題就在於有時你會很頭疼!因爲在每一個要到該全局變量的地方,你都要添一句gloal x,還有就是如果你在一個地方修改了
   x的值,那麼所有x的值就都變了!有的時候恐怕會出現紊亂。另一個更重要的問題在於,套用C++的一句話,全局變量破壞了程序的封裝性!所以,全局變量 是能少用盡量少用。
            

      3. 運用UserData傳遞參數(gui內)
     直接通過對象的userdata屬性進行各個callback之間的數據存取操作。首先必須將數據存儲到一個特定的對象中,假設對象的句柄值爲 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);

    4.應用setappdatagetappdata與 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')');

當在主子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定義全局變量好!

    5.結合handles和guidata函數(gui內,不推薦使用,經常出現問題,比如在handles中添加了變量對象Y後可能就會擠掉 handles另外一個對象)
   他的使用格式如下,如果你在pushbutton1中得到一個變 量X,相傳出去,那麼在pushbutton1的callback中,在得到X後添加如下代碼:
            handles.X=X;
            guidata(hObject,handles)(注意,一定是兩行連寫)
   在pushbutton2中要用到X是,在其callback先添加  X=handles.X; 即可得到X的值。


    6. 運用save和load(importdata)傳遞參數(gui內和gui間)
    將某變量x的值先存到磁盤,用的時候在調用。格式如下:save('*.mat','x');用的時候就用load('*.mat'),但這樣只是把x讀 到了matlab workspace,不會用顯示,你還要再去查看這個變量名,    然後才能用,建議使用p=importdata('*.mat'),p是一個結構體,可以隨意使用了。當然,這種方式涉及到磁盤讀寫,速度當然會有影響 的,一般情況不用,通常用在保存以及導入某個變量時!

 

m文件中每個callback都可以視爲一個獨立執行的接口,也就說每個callback之間無法做溝通操作,因此變量傳遞會有問題,有以下幾種方式可以解決不同的回調函數之間的數據傳遞問題:
1.使用全局變量
當前有一組運算數據放在a必須在tag名稱爲pushbutton1
與pushbutton2所對應的對象callback中使用,因此必須在雙方的callback中都設置這個數據a爲全局變量。
functin pushbutton_1(hobject,eventdata,handles)
%hobjecet 按鈕一的句柄
%handles 用作存儲用戶數據的句柄(下一小節會用到)
global a   %將a聲明爲全局變量
functin pushbutton_2(hobject,eventdata,handles)
global a   %將a聲明爲全局變量
通過以上的聲明,a就成爲跨越兩個按鈕的數據
2.應用對象的userdata
直接通過對象的userdata屬性進行各個callback之間的數據存取操作。首先必須將數據存儲到一個特定的對象中,假設對象的句柄值爲 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);
3.應用setappdatagetappdata與rmappdata函數
使用上面三個函數最有彈性處理數據的傳送問題,與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'')');
4 結合handles和guidata函數(不推薦使用)
其方式如下:
handles.變量名稱=變量值                    %取得數據
guidata(h,dhandles)                               %存儲數據
如果有一個callback中運算了兩個值Y和F,而這兩個值是在另一個callback中使用的,就可以使用以下程序了:
handles.Y=Y;
handles.F=F;
guidata(hObject,handles);
在另一個要使用到這兩個變量的callbvack中,可以使用以下程序獲得:
Y=handles.Y;
F=handles.F;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章