handles 在gui中就是一个储存各种句柄和数据结构体.
guidata()函数是用来储存和取出这个结构体的函数, 将handles结构体存入figure的特定储存空间中或从中取出, 因此有两种用法:
1. guidata(hObject, handles); %%储存handles
2. handles = guidata(hObject); %%取出handles
handles仅仅只是一个结构体, 在函数之间传递时,如:
function push1_Callback(hObject, eventdata, handles)
handles.data1 = 'heygirl'; %将字符串存入handles结构体
guidata(hObject, handles);
传入的只是handles的值, callback函数中的handles改变时, figure特定存储空间中的handles并没有改变. 因此必须使用guidata(hObject, handles)将改变的handles储存. hObject只是为了找到figure的特定储存空间, 可以是figure中的任意句柄. handles的传递就好像是函数间的形参与实参, 但是这里的形参可以通过guidata(hOject, handles)改变实参.
guidata 函数有两种使用方法,
其一是:
GUIDATA(H, DATA)
。 实现的是把指定的 DATA 变量内容储存到当前figure窗口 所开辟的某个存储变量(the figure's application data),我们不必深究具体是在哪里,反正是一块存储空间,把DATA交给当前窗口,让它去保存好了。DATA 可以是普通变量,也可以是结构体。H是当前窗口句柄或者当前窗口内控件句柄。
其二是:
DATA = GUIDATA(H) 。把之前存储的内容赋值给变量DATA。
英文帮助文档如下:
GUIDATA Store or retrieve application data.
GUIDATA(H, DATA) stores the specified data in the figure's
application data.
H is a handle that identifies the figure - it can be the figure
itself, or any object contained in the figure.
DATA can be anything an application wishes to store for later
retrieval.
DATA = GUIDATA(H) returns previously stored data, or an empty
matrix if nothing was previously stored.
MATLAB帮助文档举了个很好的例子,如下:
... 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')));
问题:
关于 guidata(hObject,handles)语句的。。
这个好理解,我们自己定义了handles的域变量,如handles.a,并且
该变量需要在不同控件中共享
,通常做法是在相应的控件call_back函数结束前加上guidata(hObject,handles),
代表把handles内容储存到当前figure窗口 所开辟的某个存储变量
(the figure's application data),这个没问题。但是我觉得在每个回调函数的开头应该加上 handles = guidata(hObject) ,因为这样才能返回之前存储的handles,这个handles数据才是更新后的。。。可是我们往往在A控件的回调函数中定义了handles.a,同时调用了guidata(hObject,handles)。 但是B控件要使用handles.a变量时候,并不不要handles = guidata(hObject)语句。直接使用handles.a 也没问题。。不知道这是什么原因。请求解释!希望在GUI方面有研究的朋友,帮忙解释下,谢谢了!
网友的回复:
简单说:在进入 Callback 函数时,会自动生成3个变量:
1.handles = 全部物件句柄
2.eventdata = 该物件相关变量
3.hObject = 该物件本身句柄
所以就算不加入 handles = guidata(hObject) 也是沒问题的
还有上面 handles = guidata(hObject)
必須修改成 handles = guidata(gcf) or handles = guidata(handles.figure1)
經常會有人使用錯誤,直接输入 hObject 這是指該物件的句柄
如果在不同物件时, guidata(hObject) 会导致资料保存在該物件,而非当前窗口
------------分割线---------------------------------------------------------------
1.数据怎么在不同的控件之间传递
先看在一个GUI界面内部的传递的数据
每一个控件的回调函数头:
function myc_Callback(hObject, eventdata, handles)
第一个参数是
hObject
,是跟这个callback所关联的控件的handles,在它自己的callback下,可以用代号-> hObject 来调用它。。不用管那么麻烦的概念,只用知道,
控件自己的回调函数调用自己的属性,只用hObject.属性名
就可以了(中间一点)。
第二个参数是MATLAB的保留参数
第三个
handles
,是这个
GUI界面的代号
。可以通过它获取这个界面的所有信息。所以在控件A自己的回调函数中,要获取或者设置别的控件的属性,就用handles.别的控件Tag.属性
------------------------------
handles hObject 都是结构体。正常的编程概念。
handles格式是一个存放数据的缸。控件的handles是小缸,它的名字叫做hObject;GUI界面的handle是一个大缸,并且这个缸名字也叫做handles;大缸里存放了所有的小缸和所有用户数据,你只需
handles.控件A的tag 就可以存取控件A的信息。
跨控件,用handles,在本控件,直接用hObject
GUIDE创建了一个大缸:结构体handles,handles包括了figure中所有控件的句柄,也包括figure的句柄
比如一个GUI包括一个edit text, 一个panel,一个pop-up menu和一个push button,GUIDE用每个控件的tag来命名handle,handles结构体内容如下:
那我怎么把自己计算出或者别的什么数据放到这个缸里呢?
^_^ 在任何地方
handles.自己的变量名 = 某些值 (其实也就是给结构体添加成员变量)
这样你就定义了自己的变量。
在任何地方
b=handles.自己的变量名 (结构名加点号来引用成员变量)
就可以得到这个变量值,同样也可以修改它。
别忘了使用
guidata(hObject, handles);(不用改,直接黏贴) 在函数末尾来保存你对handles和hObject的操作。(不然你自定义的变量就没了)
%guidata( 视窗句柄 , 全部句柄 ),如果视窗句柄位置不是视窗句柄,而是一个控件的句柄,那么这个控件的父视窗(parent figure)会被调用。所以guidata中的视窗句柄 可以是figure的句柄,也可以是figure内所包含的控件的句柄,不管是哪种情况,最终handles会和figure相关联。全部句柄即GUI句柄handles
2. 怎么在控件callback函数体之外获取控件和用户自己的数据
GUI界面的handles保存着所有控件的信息以及用户自己的数据,所以只要获取GUI的handles就可以获取所有。
比如在自己定义的函数里获取handles,只需将handles作为参数传进去就可以
function my_function(handles)
% handles是GUI的handles
%调用GUI内任意一控件的信息
%
get(handles.你控件的tag,'要获取的属性名');
temp=get(handles.my_popup,'Value');
计时timer中:
% 在figure创建完成后创建 timer 对象,将handles传入Callback函数
t = timer('TimerFcn', {@timerCallback,
handles
}, 'ExecutionMode', 'fixedDelay', 'Period', 1.0);
% 设置窗口关闭的回调函数
set(handles.figure1, 'DeleteFcn', {@DeleteFcn, t});
% 启动定时器
start(t);
%传入handles
function timerCallback(obj, event,
handles
)
temp=get(
handles
.my_popup,'Value');
end
% 窗口关闭的响应函数-停止计时器
function DeleteFcn(hObject, eventdata, t)
stop(t);
end
3 在其他子函数或者非figure内控件的callback内保存用户数据到guidata
GUIDE中,
GUIDE生成了一个包括所有GUI句柄的结构体:handles,我们可以保存用户数据到其中
(GUIDE generates a handles structure that contains the GUI's handles. You can add your own data to it)
guidata( 视窗句柄 , 全部句柄 )
如果视窗句柄位置不是视窗句柄,而是一个控件的句柄,那么这个控件的父视窗(parent figure)会被调用。所以guidata中的视窗句柄
可以是figure的句柄,也可以是figure内所包含的控件的句柄,不管是哪种情况,最终handles会和figure相关联。全部句柄即GUI句柄handles
guidata(hObject, handles);
在figure控件callback之内调用guidata(hObject, handles);,hObject是控件的句柄。如果在其他子函数或者非figure控件的callback知中使用guidata保存数据,hObject就不再是控件句柄,会出错。所以我们要用
figure的句柄
代替hObject,即handles.figure1
guidata(
handles.figure1
, handles);
例如在上述计时器的callback函数中保存data: guidata(
handles.figure1
, handles);
4、在不同GUI之间传递数据
传入
那就来看
打开一个GUI界面时,传给他的参数有哪些
。
function mygui_OpeningFcn(hObject, eventdata, handles, varargin)
所有的启动参数都是通过
varargin
传到它的OpeningFcn里面的。那启动参数可以是哪些呢?
1、figure,也就是窗口参数
。
比如说position之类
例如:打开这个GUI时,使用这个命令
mygui('Position',[434 234 234 34])
则表示打开窗口在这个位置;还有哪些可控属性可以查help。
2、自定义参数 。
如果传入的参数不是figure的属性(matlab查找不到你输入的属性名),则你输入的参数作为一个向量存放在varargin里面。
比如mygui('路人甲','80‘),那varargin{1}存放了'路人甲',varargin{2}=’80‘
那mygui中对这读取两个数据进行反应,就达到了传入参数的目的。
传出
那怎么把数据传出来呢?
将你
要输出的数据存在handles.output里面
在GUI任意地方
handles.output=数据1;
handles.secend_output=数据2;
然后在GUI的outputFcn里面加上
varaginout{1}=handles.output;
varaginout{2}=handles.secend_output;
这样就把数据传出来了。
看每一个GUI的最外层的那句
function varargout = mygui(varargin) 看输入输出,就是这样了。把GUI本身就是一个函数,
b=mygui(一些传入的参数) 就执行GUI并返回结果
则b就得到了传出来的结果。