在用多个matlab的figure进行数据交互时,数据传入是较为简单的,可以直接用function的形参实现,但如何把数据传回,是个比较麻烦的问题。
在GUIDE下,系统自动生成了output_fcn函数,可以用它来实现从子窗口到主窗口的数据传回,但如果是手写figure,就没有这个函数了。为此,考虑用setappdata和getappdata来实现这个功能。
写了个简单的demo程序,先看下效果:
程序一上来,先打开上面的主窗口,里面的编辑框里写了一些字符参数。点击按钮,可以打开第二个窗口,也就是子窗口,里面传入了主窗口里的参数。
子窗口也有一个编辑框和一个按钮,编辑框里显示的是从主界面传入的变量。可以在这里手改。改动后,点击按钮,子窗口就自动消失,然后改动的变量在主界面里显示。
这就实现了数据的互相传递了。
下面,直接把代码附上,在讲解。
function main
% 创建示例数据
data.info.name = 'test';
data.info.date = '2022-10-10';
data.info.flag = 'true';
data.test = rand(10);
info = data.info;
% 创建窗口
hfig = figure('Tag','main_fig123',...
'Name','主窗口',...
'NumberTitle','off',...
'Units','normalized',...
'position',[0.3 0.3 0.4 0.4],...
'Toolbar','none',...
'MenuBar','none',...
'Resize','on',...
'DockControls','off',...
'Color',[0.9255 0.9137 0.8471]);
% 创建按钮控件
hbtn = uicontrol(hfig,...
'Style','pushbutton',...
'String','打开子窗口',...
'Tag','ok_button',...
'units','normalized',...
'position',[0 0.8 1 0.1],...
'Callback',{@sub});
% 创建编辑控件
hed1 = uicontrol(hfig,'Style','edit','Tag','edit1','String',info.name,...
'units','normalized','position',[0.2 0.6 0.6 0.1]);
hed2 = uicontrol(hfig,'Style','edit','Tag','edit2','String',info.date,...
'units','normalized','position',[0.2 0.4 0.6 0.1]);
hed3 = uicontrol(hfig,'Style','edit','Tag','edit3','String',info.flag,...
'units','normalized','position',[0.2 0.2 0.6 0.1]);
setappdata(hfig,'info',info);
end
function sub(hObj,event)
hfig = findobj('Tag','main_fig123');
if length(hfig)>1
return;
end
info = getappdata(hfig,'info');
% 创建窗口
hfig_sub = figure('Tag','main_fig',...
'Name','子窗口',...
'NumberTitle','off',...
'Units','normalized',...
'position',[0.4 0.4 0.3 0.3],...
'Toolbar','none',...
'MenuBar','none',...
'Resize','on',...
'DockControls','off',...
'Color',[0.9255 0.9137 0.8471]);
% 创建按钮控件
hbtn = uicontrol(hfig_sub,...
'Style','pushbutton',...
'String','数据传回',...
'Tag','ok_button',...
'units','normalized',...
'position',[0 0.7 1 0.1],...
'Callback',{@sub_btn_click});
% 创建编辑控件
hed1 = uicontrol(hfig_sub,'Style','edit','Tag','sub_e1','String',info.name,...
'units','normalized','position',[0.2 0.3 0.6 0.1]);
end
function sub_btn_click(hObj,event)
% 查找子窗口的编辑框
hed1 = findobj('Tag','sub_e1');
name = get(hed1,'String');
% 查找数据
hfig = findobj('Tag','main_fig123');
if length(hfig)>1
return;
end
info = getappdata(hfig,'info');
% 写入新数据
info.name = name;
setappdata(hfig,'info',info);
% 关闭当前窗口
close(gcf);
% 更新主窗口控件
hed1 = findobj('Tag','edit1');
set(hed1,'String',info.name);
end
程序不长,里面用两个函数分别实现了主窗口和子窗口,另外对两个按钮的回调函数也进行了实现。主要逻辑是:
- 在主程序里先把要传递的数据存入主程序的某个控件中,比如就主窗口。
- 主程序点击按钮,召出子窗口。
- 子窗口找到主窗口的句柄,然后把appdata传过来,再显示到控件上。
- 子窗口点击按钮,将控件里的信息保存到appdata中(这里的信息是新信息)。这里其实已经完成了数据传递,只要关闭窗口,并实现主程序的显示逻辑即可。
还是很简单的吧,而且都没用到uiwait和uiresume。