GUI之間的信息傳遞
1.問題描述
下面是查找過的關鍵詞,中英文具備,但是很少能夠查到答案!不過在此還是要總結一下,如果有幸能幫到別人,倒也不錯!!!
1.1 搜索使用過的關鍵詞
- matlab 使用一個GUI打開另一個GUI?
- matlab findobj爲空,但是有標籤?
- findobj報空 多個GUI窗口之間的控件調用
- 多個GUI窗口之間的控件調用?
- 此類型的變量不支持使用點進行索引?
- matlab 子GUI中 此類型的變量不支持使用點進行索引?
- dot indexing not supported for this type of variable?
- How to pass data from one GUI to another?
- How to call another GUI and let the rest code in GUI1 wait until GUI2 finishes executing?
- How to: Close GUI 1, transfer data to GUI 2, open GUI 2 (and back again)?
- matlab use GUI1 open GUI2?
1.2 具體描述
我想先打開一個GUI1,然後在這個GUI1中通過,點擊按鈕來打開GUI2,在GUI2中會展示GUI1中出現的一張圖片,然後在GUI2中有一個按鈕可以把這個圖片下載下來?
但是在實現過程中,往往是可以在GUI1中,直接繪製GUI2中axes中的圖像,但是打開GUI2之後,卻不能獲取到GUI2中的圖像?
跳轉2.3的實現。
1.3 實例展示 & 復現BUG
備註:在實例中添加了一個小小的流程,GUI1打開GUI2之後會直接在GUI2的axes1上顯示GUI裏面出現的圖,然後GUI2中有一個顯示axes2的按鈕,會將axes1中的圖片,顯示到axes2中。
備註:右側有一個框,錄製完畢之後沒有不知道應該怎麼去掉,感覺好難受 。
實現過程中可能會寫出來的源碼:
1.3.1 案例1
GUI_1 button:【顯示圖片】
備註:點擊按鈕讀取一張圖片,然後在axes1中繪製出來。
% #--- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% #hObject handle to pushbutton1 (see GCBO)
% #eventdata reserved - to be defined in a future version of MATLAB
% #handles structure with handles and user data (see GUIDATA)
global a_pic;
a_pic=imread('D:\MATLAB\DEMOCODE\Export_test\input\doll.png');
axes(handles.axes1);
imshow(a_pic);
% #備註:在matlab中註釋需要使用%,但顯示並非特別好看,所以都加了#註釋。
GUI_1 button:【打開GUI_2】
% #--- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% #hObject handle to pushbutton2 (see GCBO)
% #eventdata reserved - to be defined in a future version of MATLAB
% #handles structure with handles and user data (see GUIDATA)
global a_pic; %#加載的圖片
open('GUI_2.fig'); %#打開GUI_2
mr_handles=guihandles; %#句柄,返回的是GUI_2的句柄
axes(mr_handles.axes1); %#定位到GUI_2的axes1
imshow(a_pic); %#在定位好的地方繪製圖片
備註:上面代碼僅僅是返回了GUI_2的句柄,這樣將會導致一些列的問題。
GUI_2 button:【顯示axes2】
%# --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
%# hObject handle to pushbutton1 (see GCBO)
%# eventdata reserved - to be defined in a future version of MATLAB
%# handles structure with handles and user data (see GUIDATA)
im=getimage(handles.axes1);
axes(handles.axes2);
imshow(im);
會有如下報錯:不支持使用點進行索引。
1.3.2 案例2
由於開始寫GUI的時候就遇到過類似問題,直接打開.fig文件會有這樣的問題,所以能不能打開.m的文件,於是:
open('GUI_2.m')
很遺憾的,這樣是不可行的,會得到一個不太正確的句柄,實際上得到的是GUI_1的,但是只得到了figure和兩個button的,沒有axes的!!
然後,便開始另謀他術,使用findobj函數,在GUI中直接進行查找對應句柄,然後使用改句柄修改欲意修改的值,如下:
% #--- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% #hObject handle to pushbutton1 (see GCBO)
% #eventdata reserved - to be defined in a future version of MATLAB
% #handles structure with handles and user data (see GUIDATA)
axes1=findobj(0,'Tag','axes1'); %#獲取axes1的句柄
im=getimage(axes1);
% #im=getimage(handles.axes1);
axes(handles.axes2);
imshow(im);
但是上述的獲取方法,在通過GUI_1打開GUI_2的情況下,是獲取不到的!!!
但是直接打開‘GUI_2.m’文件,是可以獲取到的!!!!!
】
上述代碼代碼帶來的直接後果如下:
2.GUI之間的信息傳遞
2.1 通過global
- 通過global可以在同一個GUI下,不同函數之間傳遞信息
- 通過global可以在GUI之間,傳遞消息
- 備註:使用的時候,都需要使用global關鍵字,定義相同變量名
%#在不通過函數之間傳遞值
%#GUI_1 b1_Callback():GUI_1的按鈕1的Callback函數
global pic;%#定義pic變量
pic=imread('one_picture.png');%#存儲一張圖片
%#GUI_1 b1_Callback():GUI_1的按鈕2的Callback函數
global pic;%#使用全局變量pic
imshow(pic);%#展示圖片'one_picture.png'
%----------------------------------------------------%
%----------------------------------------------------%
%#在GUI之間傳遞值
%#GUI_1 b1_Callback:GUI_1的按鈕1的Callback函數
global pic;%#定義pic變量
pic=imread('one_picture.png');%#存儲一張圖片
%#GUI_2 b1_Callback:GUI_2的按鈕1的Callback函數
global pic;%#使用全局變量pic
imshow(pic);%#展示圖片'one_picture.png'
%#
備註:通過global傳遞方式可能不太好,也有其他傳遞的方式,可以參考下面的鏈接。
鏈接:Matlab GUI,全局變量,單個窗體內各個函數之間傳遞數據
鏈接:Matlab中guidata()的用法以及如何幫助參數在GUI間傳遞
裏面提到了使用guidata進行數據存取與更新的操作,感覺可能會有用,但是還沒有仔細研究。
2.2 通過setappdata & getappdata
alpha=imread('alpha.png');
%#在根路徑下聲明一個tag爲'alpha_data',然後將alpha存儲在其中
%#可以寫在任意GUI的任意函數體中
setappdata(0,'alpha_data',alpha);
%#在其他的GUI中,取出tag爲'alpha_data'的變量
%#同樣可以寫在任意位置,但最好能保證邏輯上的先set後get
alpha=getappdata(0,'alpha_data');
2.3 通過handles
繼續實現1.2中的描述的功能,通過handles的相關實現如下:
GUI_1 的【打開GUI_2】按鈕:
%# --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
%# hObject handle to pushbutton2 (see GCBO)
%# eventdata reserved - to be defined in a future version of MATLAB
%# handles structure with handles and user data (see GUIDATA)
global a_pic;
handles.GUI_2_handle=[];%#空的變量,用來存儲GUI_2的handle
if isempty(handles.GUI_2_handle)
handles.GUI_2_handle=GUI_2;%#打開GUI_2同時存儲GUI_2的handle
end
GUI_2_data=guidata(handles.GUI_2_handle);%#獲取GUI_2 handle的結構體數據
axes(GUI_2_data.axes1);%#定位到GUI_2的axes1
imshow(a_pic);%#在對應位置繪製圖片
備註:雖然不明白具體的數據流動方式,但是存儲了GUI_2的handle之後,在GUI_2被打開之後,不會出現1.3中的相關bug,可以直接使用dot方式獲取值。
So?這是爲什麼呢????
在GUI_2中【顯示axes2】按鈕中的代碼如下:
%# --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
%# hObject handle to pushbutton1 (see GCBO)
%# eventdata reserved - to be defined in a future version of MATLAB
%# handles structure with handles and user data (see GUIDATA)
im=getimage(handles.axes1);
axes(handles.axes2);%#可以直接使用dian索引方式
imshow(im);
3.相關鏈接
問題性:
- How to call another GUI and let the rest code in GUI1 wait until GUI2 finishes executing?
- How to: Close GUI 1, transfer data to GUI 2, open GUI 2 (and back again)?
- how to pass data to sub-gui using guidata?
- findobj報空 多個GUI窗口之間的控件調用
解答性:
- matlab and stuff: A simple example of multiple GUIs working together[需要VPN]
- Matlab GUI界面
- MATLAB 中gcf、gca 以及gco 的區別
- Matlab-setappdata;getappdata
資料性:
4.源碼
在博客中的代碼是比較完整的,其實可以不用下載實例,畢竟是消耗積分的。