声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 5453|回复: 6

[GUI界面] [原创]关于guidata和guihandles的一点心得

[复制链接]
发表于 2007-1-13 13:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
这两天 help guidata and help guihandles 了一下,明白了一些以前没有注意的问题,在这里介绍一下,欢迎大家讨论并指正:

  1. ... excerpt from the GUI setup code ...

  2.     f = openfig('mygui.fig');
  3.     data = guihandles(f); % initialize it to contain handles
  4.     data.errorString = 'Total number of mistakes: ';
  5.     data.numberOfErrors = 0;
  6.     guidata(f, data);  % store the structure

  7.     ... excerpt from the slider's callback ...

  8.     data = guidata(gcbo); % get the struct, use the handles:
  9.     set(data.valueEdit, 'String',...
  10.         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
实际上这个handlesMATLABGUI编程中最常用的一个句柄管理变量。
handles的生成:handles = guihandles( figurehandle );figure中所有对象中“Tag”属性有值的句柄的handle采集在一起。handles是结构名,每个“Tag”域名里保持此对象的句柄。
handles的保存:guidata( figurehandle, handles );handles将保存在figure对象的“ApplicationData”的一个域名里。
handles的使用:handles = guidata( h );其中为figure中任意一个对象的句柄。
=========================================================

因此,如果用户定义的域没有做save的操作,则在后续的处理中,不能访问该域,以下是对上述两种窗体的不同情形检测的结果,得到的结论是一样。

===============普通的一个figure====================================================

  1. f = figure(1);
  2. data = guihandles(f); % initialize it to contain handles
  3. data.a = 'Total number of mistakes: ';
  4. guidata(f, data);  % store the structure in the figure's application data
  5. data.b = 0;

  6. c = guidata(f); % returns previously stored data
  7. c
复制代码


在输出的c中,只有域a的数据,没有域b的数据。如果此时把guidata(f, data);注释掉,则c为空,就连句柄f中所有资源的handles也没有记录下来,说明数据域和句柄域分开存放(也许matlab实际存储时候对于资源的句柄只有一个副本,这个没有深究),guihandles读取的是句柄域信息,guidata读取的是数据域(包括句柄和用户数据)信息。
===========================================================

===============fig文件方式的GUI窗体(部分代码)=========================================

  1. % --- Executes on button press in pushbutton1.
  2. function pushbutton1_Callback(hObject, eventdata, handles)
  3. % hObject    handle to pushbutton1 (see GCBO)
  4. % eventdata  reserved - to be defined in a future version of MATLAB
  5. % handles    structure with handles and user data (see GUIDATA)
  6. handles.abc=2;
  7. %guidata(hObject, handles);

  8. % --- Executes on button press in pushbutton2.
  9. function pushbutton2_Callback(hObject, eventdata, handles)
  10. % hObject    handle to pushbutton2 (see GCBO)
  11. % eventdata  reserved - to be defined in a future version of MATLAB
  12. % handles    structure with handles and user data (see GUIDATA)
  13. 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的时候就直接保存到其父对象(这里为该GUIfigure)中,所以无论自定义的域在哪个buttonsave,通过button1或通过button2都可以读取到该域的数据。
========================================================

update(additive words) in blue

[ 本帖最后由 eight 于 2007-1-16 13:14 编辑 ]

评分

1

查看全部评分

回复
分享到:

使用道具 举报

发表于 2007-1-16 09:52 | 显示全部楼层
支持八兄!辛苦了!为大家贡献很大啊!:handshake
 楼主| 发表于 2007-1-16 12:32 | 显示全部楼层
原帖由 yangzhijing521 于 2007-1-16 09:52 发表
支持八兄!辛苦了!为大家贡献很大啊!:handshake



呵呵,应该的,谢谢大家的支持!:loveliness:

[ 本帖最后由 eight 于 2007-1-16 12:48 编辑 ]
发表于 2007-1-17 08:11 | 显示全部楼层
就快放假回家了,在家也没电脑用,多带几个eight贴回去研究吧,哈哈:lol 。
发表于 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");',...
    '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这是哪里出的问题?谢谢
 楼主| 发表于 2007-1-17 15:29 | 显示全部楼层
原帖由 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等关键词外面使用两个单引号(非一个双引号),应该就没有问题:


  1. uimenu(hplot,'Label','&Sin','callback',['t=-pi:pi/20:pi;','plot(t,sin(t));',...
  2.     'set(hgon,''Enable'',''on'');','set(hgoff,''Enable'',''on'');',...
  3.     'set(hbon,''Enable'',''on'');','set(hboff,''Enable'',''on'');']);
复制代码
发表于 2007-1-17 19:19 | 显示全部楼层
谢谢了:)

太疏忽了噢:(
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-12-13 04:55 , Processed in 0.072373 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表