您的位置:首页 > 编程语言 > MATLAB

Matlab参数传递手把手教程

2013-12-09 11:09 204 查看
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如下
function pushbutton1_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作更改也没有效果了。
function Gui2_OpeningFcn(hObject, eventdata, handles, varargin)

handles.output = hObject;
guidata(hObject, handles);
% UIWAIT makes Gui2 wait for user response (see UIRESUME)

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中加入如下代码,实现参数返回
function varargout = 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如下

function pushbutton1_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);
function varargout = 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:Manipulating a Modal Dialog Box for User Input

方法:

1)在主GUI中的OpeningFcn中,加入 uiwait(handles.figure),handles.figure中figure是主GUI的figure的tag

function changeme_main_OpeningFcn(hObject, eventdata, handles, varargin)

handles.output = hObject;

% Update handles structure

guidata(hObject, handles);

% Set waiting flag in appdata

setappdata(handles.figA,'waiting',1)

% UIWAIT makes changeme_main wait for user response (see UIRESUME)

uiwait(handles.figA);

2) 在按钮的Callback函数中增加如下代码

function buttonChangeMe_Callback(hObject, eventdata, handles)

changeme_dialog('changeme_main', handles.figA);% 第二个参数是当前主GUI的句柄!

3)在主GUI的CloseRequestFcn中增加如下代码

function figure_CloseRequestFcn(hObject,eventdata,handles)

% Check appdata flag to see if the main GUI is in a wait state

if getappdata(handles.figA,'waiting')

% The GUI is still in UIWAIT, so call UIRESUME and return

uiresume(hObject);

setappdata(handles.figA,'waiting',0)

else

% The GUI is no longer waiting, so destroy it now.

delete(hObject);

end

4)在子GUI中的OpeningFcn增加如下代码

function changeme_dialog_OpeningFcn(hObject, eventdata, handles, varargin)

% Is the changeme_main gui's handle is passed in varargin?

% if the name 'changeme_main' is found, and the next argument

% varargin{mainGuiInput+1} is a handle, assume we can open it.

dontOpen = false;

mainGuiInput = find(strcmp(varargin, 'changeme_main'));

if (isempty(mainGuiInput)) ...

|| (length(varargin) <= mainGuiInput) ...

|| (~ishandle(varargin{mainGuiInput+1}))

dontOpen = true;

else

% Remember the handle, and adjust our position

handles.changeMeMain = varargin{mainGuiInput+1}; % 把主GUI的句柄保存到handles.changeMeMain字段

% Obtain handles using GUIDATA with the caller's handle

mainHandles = guidata(handles.changeMeMain); %从主GUI的句柄guidata一下才能访问主GUI中的控件!

% Set the edit text to the String of the main GUI's button

set(handles.editChangeMe, 'String', ...

get(mainHandles.buttonChangeMe, 'String'));

% Position to be relative to parent:

parentPosition = getpixelposition(handles.changeMeMain);

currentPosition = get(hObject, 'Position');

% Set x to be directly in the middle, and y so that their tops align.

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, 'Position', [newX, newY, newW, newH]);

end

% Update handles structure

guidata(hObject, handles);

if dontOpen

disp('-----------------------------------------------------');

disp('Improper input arguments. Pass a property value pair')

disp('whose name is "changeme_main" and value is the handle')

disp('to the changeme_main figure, e.g:');

disp(' x = changeme_main()');

disp(' changeme_dialog(''changeme_main'', x)');

disp('-----------------------------------------------------');

else

uiwait(hObject);

end

5)在子GUI中的buttonOK的callback增加如下代码

function buttonOK_Callback(hObject, eventdata, handles)

text = get(handles.editChangeMe, 'String');

main = handles.changeMeMain; % 主GUI的句柄,就是varargin{2}

% Obtain handles using GUIDATA with the caller's handle

if(ishandle(main))

mainHandles = guidata(main); %从主GUI的句柄guidata一下才能访问主GUI中的控件!

changeMeButton = mainHandles.buttonChangeMe;

set(changeMeButton, 'String', text);

end

uiresume(handles.figB);

6)其余部分的代码

% --- Executes on button press in buttonCancel.

function buttonCancel_Callback(hObject, eventdata, handles)

% hObject handle to buttonCancel (see GCBO)

% eventdata reserved - to be defined in a future version of MATLAB

% handles structure with handles and user data (see GUIDATA)

uiresume(handles.figB);

% --- Executes when user attempts to close figB.

function figB_CloseRequestFcn(hObject, eventdata, handles)

% hObject handle to figB (see GCBO)

% eventdata reserved - to be defined in a future version of MATLAB

% handles structure with handles and user data (see GUIDATA)

uiresume(hObject);

% --- Outputs from this function are returned to the command line.

function varargout = changeme_dialog_OutputFcn(hObject, eventdata, handles)

% varargout cell array for returning output args (see VARARGOUT);

% hObject handle to figB

% eventdata reserved - to be defined in a future version of MATLAB

% handles structure with handles and user data (see GUIDATA)

varargout{1} = [];

delete(hObject);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: