[原创]关于guidata和guihandles的一点心得
这两天 help guidata and help guihandles 了一下,明白了一些以前没有注意的问题,在这里介绍一下,欢迎大家讨论并指正:... excerpt from the GUI setup code ...
f = openfig('mygui.fig');
data = guihandles(f); % initialize it to contain handles
data.errorString = 'Total number of mistakes: ';
data.numberOfErrors = 0;
guidata(f, data);% store the structure
... excerpt from the slider's callback ...
data = guidata(gcbo); % get the struct, use the handles:
set(data.valueEdit, 'String',...
num2str(get(data.valueSlider, 'Value')));
上面代码是从help guidata拷贝出来的,解释一下:
f = openfig('mygui.fig');%打开窗体并返回其句柄f
data = guihandles(f);%创建句柄结构体data并把窗体中所有资源添加到该句柄结构体中,这里的“资源”是指控件或者组件,以下简称句柄域。在我的测试中,用了两种不同的窗体,一种是fig文件方式的GUI窗体,另一种是普通的一个figure,得到的data分别是GUI上的控件句柄(Tag属性值作为域名)和figure上的组件句柄(这个应该是默认的,包括各菜单和工具栏等)。
guidata(f, data);%把结构体存储到句柄f中
data = guidata(gcbo); %从当前对象的句柄中获取所有资源的handles和用户的数据(即用户定义的域),这两者的总体以下简称数据域
以上是我写的解释,实际上在“[转帖]函数结构与参数传递”一文中,就有上面几个函数的介绍:
=========================================================
关于handles:
实际上这个handles是MATLAB中GUI编程中最常用的一个句柄管理变量。
handles的生成:handles = guihandles( figurehandle );将figure中所有对象中“Tag”属性有值的句柄的handle采集在一起。handles是结构名,每个“Tag”域名里保持此对象的句柄。
handles的保存:guidata( figurehandle, handles );handles将保存在figure对象的“ApplicationData”的一个域名里。
handles的使用:handles = guidata( h );其中为figure中任意一个对象的句柄。
=========================================================
因此,如果用户定义的域没有做save的操作,则在后续的处理中,不能访问该域,以下是对上述两种窗体的不同情形检测的结果,得到的结论是一样。
===============普通的一个figure====================================================
f = figure(1);
data = guihandles(f); % initialize it to contain handles
data.a = 'Total number of mistakes: ';
guidata(f, data);% store the structure in the figure's application data
data.b = 0;
c = guidata(f); % returns previously stored data
c
在输出的c中,只有域a的数据,没有域b的数据。如果此时把guidata(f, data);注释掉,则c为空,就连句柄f中所有资源的handles也没有记录下来,说明数据域和句柄域分开存放(也许matlab实际存储时候对于资源的句柄只有一个副本,这个没有深究),guihandles读取的是句柄域信息,guidata读取的是数据域(包括句柄和用户数据)信息。
===========================================================
===============fig文件方式的GUI窗体(部分代码)=========================================
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdatareserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
handles.abc=2;
%guidata(hObject, handles);
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton2 (see GCBO)
% eventdatareserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
handles
假设先运行button1,后运行button2,则button2回调函数中的handles没有abc域。另外,有两个值得注意的地方,其一是在各回调函数中不需要用类似data = guidata(gcbo);的语句,以下是matlab的解释(help guidata 就可以看到):Note that GUIDE generates callback functions to which a structure of handles is passed automatically as an input argument. This eliminates the need to call "data = guidata(gcbo);" in callbacks written using GUIDE. 其二,假如button1回调函数中的guidata(hObject, handles);没有注释掉,则button2回调函数中的handles是有abc域的,这一点毫无疑问。但是细心的读者会发现,两个回调函数的hObject是不同的,也就是说,在button1回调函数中的guidata(hObject, handles);是把handles存入button1对应的hObject中,那为何在button2的回调函数中能够通过省略的“handles = guidata(gcbo);”语句把新增加在button1上的数据域abc读取出来呢?这个原因我没有时间具体深究下去(也许《精通GUI》一书上有,呵呵),不过我估计答案如下:根据图形对象继承关系(参见《精通GUI》一书图3.3),使用guidata函数时,会“寻根问底”地访问该对象的父对象(这里为该GUI的主figure);或者save的时候就直接保存到其父对象(这里为该GUI的figure)中,所以无论自定义的域在哪个button中save,通过button1或通过button2都可以读取到该域的数据。
========================================================
update(additive words) in blue
[ 本帖最后由 eight 于 2007-1-16 13:14 编辑 ] 支持八兄!辛苦了!为大家贡献很大啊!:handshake 原帖由 yangzhijing521 于 2007-1-16 09:52 发表
支持八兄!辛苦了!为大家贡献很大啊!:handshake
呵呵,应该的,谢谢大家的支持!:loveliness:
[ 本帖最后由 eight 于 2007-1-16 12:48 编辑 ] 就快放假回家了,在家也没电脑用,多带几个eight贴回去研究吧,哈哈:lol 。 我看书上的一个例子
uimenu(hplot,'Label','&Sin','callback',['t=-pi:pi/20:pi;','plot(t,sin(t);',...
'set(hgon,"Enable","on");','set(hgoff,"Enable","on");',...
'set(hbon,"Enable","on");','set(hboff,"Enable","on");']);
出现这样的错误:
??? Error: Unexpected MATLAB expression.
??? Error using ==> t=-pi:pi/20:pi;plot(t,sin(t)set(hgon,"Enable","on");set(hgoff,"Enable","on");set(hbon,"Enable","on");set(hboff,"Enable","on");
??? Error while evaluating uimenu Callback
请问eight这是哪里出的问题?谢谢 原帖由 lxq 于 2007-1-17 13:41 发表
我看书上的一个例子
uimenu(hplot,'Label','&Sin','callback',['t=-pi:pi/20:pi;','plot(t,sin(t);',...
'set(hgon,"Enable","on");','set(hgoff,"Enable","on&q ...
plot(t,sin(t); 那里漏了一个括号,并且注意Enable等关键词外面使用两个单引号(非一个双引号),应该就没有问题:
uimenu(hplot,'Label','&Sin','callback',['t=-pi:pi/20:pi;','plot(t,sin(t));',...
'set(hgon,''Enable'',''on'');','set(hgoff,''Enable'',''on'');',...
'set(hbon,''Enable'',''on'');','set(hboff,''Enable'',''on'');']);
谢谢了:)
太疏忽了噢:(
页:
[1]