多个GUI传参数.docx
《多个GUI传参数.docx》由会员分享,可在线阅读,更多相关《多个GUI传参数.docx(11页珍藏版)》请在冰豆网上搜索。
多个GUI传参数
1为什么要多个GUI之间参数传递?
在matlab编写GUI界面时候,我们要很多个界面,例如figA和figB,figA中的一个按钮来打开figB,当需要在figB中设置一些参数,然后把那些参数值返回给figA中的按钮的那个callback,以在figA中使用figB传过来的数据。
"为了这个整了好几天头都了。
今天终于看到希望了哈哈,做个备注。
"------首先感谢原作者无私分享他的知识,是你节省了我的学习时间。
2缘起
昨天在网上看了好多帖子,好多前辈都是把他成功的经验分享了一下,没有给具体的多个GUI之间数据传递的例子,或者举的例子没有详细的说明核心的参数传递机制。
这给初学者带来了学习的瓶颈,增加了入门难度。
此文的宗旨在于详细介绍多GUI之间数据传递的原理,结合实际例子深入浅出的把GUI参数传递的方法教给需要这方面知识的人。
愿大家得大智慧,发无上心!
3正文
依次实践了下网上流传的多个GUI之间数据传递方式,我个人感觉好用的由以下三种方案,同时也推荐大家在实际的项目中使用,因为根据软件工程的思想不会影响整个工程的质量。
下面依次介绍
(1)思想:
采用setappdata,getappdata在子GUI中传递数据,通过varargout将子GUI的参数传递给主GUI,uiwait(指定句柄),通过uiresume(指定句柄)返回OutputFcn。
方法:
1)主GUI中放一个Button,无参数调用子GUI,其CallBack如下
functionpushbutton1_Callback(hObject,eventdata,handles)
mySettings=Gui2;
set(handles.text1,'string',mySettings.weight)
2)子GUI的figure的tag为figB,设置GUI子程序的OpeningFcn函数的结尾加上uiwait(handles.figB),这是因为在子GUI的OpenFcn中,如果不加uiwait,程序会直接运行到下面,执行OutputFcn。
也就是说程序一运行,返回值就确定了,再在其它部分对handles.output作更改也没有效果了。
functionGui2_OpeningFcn(hObject,eventdata,handles,varargin)
handles.output=hObject;
guidata(hObject,handles);
%UIWAITmakesGui2waitforuserresponse(seeUIRESUME)
uiwait(handles.figB);
3)在子GUI的pushbutton1的callback中加入如下代码,实现参数设置
spec_data.length=20;
spec_data.weight=200;
setappdata(handles.figB,'settings',spec_data);%如果保存数据到0句柄,即保存到matlab主程序,这类似于全局变量了
uiresume(handles.figB);%注意完成了参数设置后然后再uiresume,网上好多帖子都故弄玄虚,没讲明白。
其实就这么简单
4)在子GUI的OutputFcn中加入如下代码,实现参数返回
functionvarargout=Gui2_OutputFcn(hObject,eventdata,handles)
%varargout{1}=handles.output;%默认的被注释掉了
tmp=getappdata(handles.figB,'settings');
varargout{1}=tmp;%注意一个结构体中包含了很多参数,原来多个返回值可以放在一个结果体中
(2)思想:
uiwait(gcf),通过关闭当前子GUI时自动resume,然后执行OutputFcn中返回值的语句。
其实要说明的是,此方法把参数放在handles=0,不用varargout的话,在主GUI中getappdata(0,'settings');也可以直接获得settings的值。
方法:
1)主GUI中放一个Button,无参数调用子GUI,其CallBack如下
functionpushbutton1_Callback(hObject,eventdata,handles)
mySettings=Gui2;
set(handles.text1,'string',mySettings.weight)
2)子GUI中的pushbutton1的callback中加入如下代码,实现参数设置
spec_data.length=20;
spec_data.weight=200;
setappdata(handles.figB,'settings',spec_data);%如果保存数据到0句柄,即保存到matlab主程序,这类似于全局变量了
%uiresume(handles.figB);
3)子GUI中OpeningFcn函数的结尾不用加上uiwait(handles.figB),在OutputFcn的返回语句之前增加uiwait(gcf);
functionvarargout=Gui2_OutputFcn(hObject,eventdata,handles)
%varargout{1}=handles.output;
uiwait(gcf);%等待子GUI关闭后,然后自动resume,执行以下返回语句
tmp=getappdata(0,'settings');
varargout{1}=tmp;
(3)思想:
通过varargin将主GUI的句柄传给子GUI,这样子GUI拥有了主GUI的句柄后就相当于VC++中View类中包含Doc类对象的指针一样,不用varargout,操作很方便额!
该例子来自于matlab自带的Example:
ManipulatingaModalDialogBoxforUserInput
方法:
1)在主GUI中的OpeningFcn中,加入uiwait(handles.figure),handles.figure中figure是主GUI的figure的tag
functionchangeme_main_OpeningFcn(hObject,eventdata,handles,varargin)
handles.output=hObject;
%Updatehandlesstructure
guidata(hObject,handles);
%Setwaitingflaginappdata
setappdata(handles.figA,'waiting',1)
%UIWAITmakeschangeme_mainwaitforuserresponse(seeUIRESUME)
uiwait(handles.figA);
2)在按钮的Callback函数中增加如下代码
functionbuttonChangeMe_Callback(hObject,eventdata,handles)
changeme_dialog('changeme_main',handles.figA);%第二个参数是当前主GUI的句柄!
3)在主GUI的CloseRequestFcn中增加如下代码
functionfigure_CloseRequestFcn(hObject,eventdata,handles)
%CheckappdataflagtoseeifthemainGUIisinawaitstate
ifgetappdata(handles.figA,'waiting')
%TheGUIisstillinUIWAIT,socallUIRESUMEandreturn
uiresume(hObject);
setappdata(handles.figA,'waiting',0)
else
%TheGUIisnolongerwaiting,sodestroyitnow.
delete(hObject);
end
4)在子GUI中的OpeningFcn增加如下代码
functionchangeme_dialog_OpeningFcn(hObject,eventdata,handles,varargin)
%Isthechangeme_maingui'shandleispassedinvarargin?
%ifthename'changeme_main'isfound,andthenextargument
%varargin{mainGuiInput+1}isahandle,assumewecanopenit.
dontOpen=false;
mainGuiInput=find(strcmp(varargin,'changeme_main'));
if(isempty(mainGuiInput))...
||(length(varargin)<=mainGuiInput)...
||(~ishandle(varargin{mainGuiInput+1}))
dontOpen=true;
else
%Rememberthehandle,andadjustourposition
handles.changeMeMain=varargin{mainGuiInput+1};
%ObtainhandlesusingGUIDATAwiththecaller'shandle
mainHandles=guidata(handles.changeMeMain);
%SettheedittexttotheStringofthemainGUI'sbutton
set(handles.editChangeMe,'String',...
get(mainHandles.buttonChangeMe,'String'));
%Positiontoberelativetoparent:
parentPosition=getpixelposition(handles.changeMeMain);
currentPosition=get(hObject,'Position');
%Setxtobedirectlyinthemiddle,andysothattheirtopsalign.
newX=parentPosition
(1)+(parentPosition(3)/2-currentPosition(3)/2);
newY=parentPosition
(2)+(parentPosition(4)/2-currentPosition(4)/2);
%newY=parentPosition
(2)+(parentPosition(4)-currentPosition(4));
newW=currentPosition(3);
newH=currentPosition(4);
set(hObject,'Positi