声明:本文内容参考《MATLAB GUI设计学习手记》
从这篇博文开始,不打算废话了,直接上干货!
gui_mainfcn函数
上篇博文对gui_mainfcn函数一带而过,本篇博文从这个函数开始,学习GUI的运行机制
function varargout = gui_mainfcn(gui_State, varargin)
%
%检查结构体gui_State的字段
gui_StateFields = {'gui_Name'
'gui_Singleton'
'gui_OpeningFcn'
'gui_OutputFcn'
'gui_LayoutFcn'
'gui_Callback'};
gui_Mfile = '';
for i=1:length(gui_StateFields)
if ~isfield(gui_State, gui_StateFields{i})
error(message('MATLAB:guide:StateFieldNotFound', gui_StateFields{ i }, gui_Mfile));
elseif isequal(gui_StateFields{i}, 'gui_Name')
gui_Mfile = [gui_State.(gui_StateFields{i}), '.m'];
end
end
%检测输入参数,若创建GUI,令变量gui_Create=ture;若执行回调函数,gui_Create=false
numargin = length(varargin);%输入参数的个数
if numargin == 0%若没有输入参数
% UNTITLED
% create the GUI only if we are not in the process of loading it
% already
gui_Create = true;
%省略部分代码
%根据变量gui_Create的值来创建GUI或执行函数
if ~gui_Create %若gui_Create=false,执行回调
%省略部分代码
else %若gui_Create = ture,创建GUI过程
%(1)是否只运行单一GUI
%(2)检查GUI的可见性
%(3)创建或更新GUI数据(handles结构体)
%(4)检查输入参数是否为【属性】和【属性值】成对出现,并设置属性,直到出现错误跳出
%(5)检查句柄可见性(HandleVisibility属性)
%(6)执行Opening函数(gui_State.gui_OpeningFcn)
%(7)根据Visible值决定是否将窗口显示到屏幕
%(8)执行Output函数(gui_State.gui_OutputFcn)
%(9)设置句柄可见性(HandlesVisibility属性)
end
%省略后续代码
创建一个GUI的过程大致分为上面9步。
由上述创建GUI的过程,得出:
- 【创建handles结构体】在【执行Opening函数】之前,所以在Opening函数中,可以使用handles结构体访问该GUI的所有组件对象。
- 当输入参数成对出现时,MATLAB会将输入参数逐对从左至右设置为对象的属性,一旦遇到未定义的属性或错误的属性设置,将不再设置后面的属性对,也不弹出错误信息,而是执行跳出属性设置的循环。
- 【执行Opening函数】在【显示窗口到屏幕】之前,至右执行完了Opening函数,GUI窗口才会课件。
GUI数据管理机制
GUI采用3种数据管理机制:GUI数据、APPlication数据和UserData属性。
- GUI数据:handles结构体
GUI数据由handles结构体保存。当运行GUIDE创建GUI时,M文件会自动生成handles结构体。handles结构体可看作哦一个数据的“容器”,包含所有的GUI对象数据。handles与对应的GUI窗口相关联,它作为第三个输入参数传递给每个回调函数(e.g.function popupmenu1_Callback(hObject, eventdata, handles)
),使得回调函数可以随意访问GUI数据。
handles结构体两个主要用途:
(1).访问GUI数据。handles结构体包含了GUI对象的Tag值和句柄信息,故回调函数可通过handles获取任何GUI数据。
e.g.对象a的Tag值为a,对象b的Tag值为b,则在对象b的callback函数中获取对象a的string值,可采用:
str = get(handles.a,'string')
或
temp=get(handles.a);
str = temp.String;
(2).在回调函数之间共享数据。在GUI中,要使一个变量成为全局变量,可将其存在handles结构体中。
e.g. 将变量a存入handles中:
handles.a=a;
guidata(hObject,handles);%更新handles数据
a=handles.a;%获取该变量值
注:handles结构体一般只将FIG文件内的GUI组件信息保存进去,而不会将M文件内创建的GUI对象存进去。即handles指存储GUI布局内放置或设置的GUI组件。
(3).两个GUI数据专用函数:guidata和guihandles.
1).guidata:存储或更新GUI数据。
guidata(obj_handle,data);
存储变量data到obj_handle所在的窗口中,作为GUI数据。若obj_handle不是figure对象句柄,将data保存到对象obj_handle的figure父类中。data可为任何类型的MATLAB变量,最典型的:data是一个结构体,可安需要增加字段到data中。
guidata任何时刻只能管理一个GUI数据,任何时刻只能有一个handles结构。
e.g.
guidata(hObject,handles);%表示将handles结构体(GUI数据)的数据更新存储到hObject对象指定的figure对象中
data=guidata(obj_handle);
返回之前存储的GUI数据,若之前没有存储GUI数据,返回空矩阵。
采用函数guidata管理GUI数据步骤如下:
a.采用语句data=guidata(obj_handle);
,获取之前的GUI数据,备份到data结构体中;
b.更新data结构体;
c.采用语句guidata(obj_handle,data)
,将data结构体存储到figure中,作为新的GUI数据。
2).guihandles:创建handles结构体
handles = guihandles(obj_handle);
字段名为obj_handle对象所对应GUI窗口内所有GUI对象(包括figure对象)的Tag属性值,字段值为这些GUI对象的句柄。
故获取handles结构体内的GUI对象句柄,可采用结构体的访问方法:handles.(字段名),即handles.(对象Tag)。
handles=guihandles;
返回当前figure的handles结构体。相当于hanfldes = guihandles(gcf);
采用guihandles创建handles结构体时,需要注意:
a.句柄隐藏的对象也包括在handles结构体中;
b.有M文件创建的GUI对象也包括在handles结构体内;
c.guihandles会清除handles结构体内非GUI对象信息的字段。
(2)APpplication数据
Application 数据(应用数据)保存在一个结构体中,Application 数据保存在GUI对象的一个未公开属性内,即ApplicationData属性,该属性的值为一个结构体。通常选择figure对象作为Application数据的保存方法。
存取Application 数据有两种方法:
1).采用get或set函数获取或修改对象的ApplicationData属性;
2).采用Application专用函数setappdata、getappdata、isappdata和rmappdata。
a. setappdata:添加新字段到指定对象Application数据中。
setappdata(h,name,value);%添加新的字段到对象h的Application 数据中,字段名为name,字段值为value。name不能与Application数据中其他的字段名冲突,value可以为任意类型数据.
b.getappdata:获取对象的Application数据。
getappdata(h,name,value);%获取对象h的Application 数据中,字段名为name
values = getappdata(h);%获取对象h的Application数据
c. isappdata
isappdata(h,name);%判断对象h的Application 数据中是否存在字段name。存在,返回真,否则返回假。
d. rmappdata
rmappdata(h,name);移除对象h的Application 数据中的字段name。
注:一个GUI中,最对只能同时存在一个GUI数据和一个Application 数据;而且GUI数据和Application 数据均为结构体。
(3)Userdata 属性
每个GUI对象都有UserData属性,它与Application 属性的区别在于:
a.UserData为公开的属性,Application Data为未公开的属性;
b.ApplicationData的值为一个结构体,而UserData的值可以为任何数据类型,例如数值、矩阵、数组、结构体、单元数组等,
UserData用于存储用户定义的数据,采用get和set函数访问。
e.g.
data = get(h,'UserData');%用于获取对象h中存储的UserData;
set(h,'UserData',datal);%y用于设置对象h的UserData为变量datal.
本篇结束语
除了以上3种方式共享GUI对象之间的数据,还可采用global定义全句变量的方式共享数据,但global数据并不随着GUI的删除而删除,而是一直存在。
一个删除GUI global变量的方法是将figure的CloseRequestFcn函数改为:
clear global; %清除全局变量
delete(hObject); % 关闭当前窗口