CallBack

   关于GUI设计是在Java上学习的,当初对这个迷迷糊糊,不太清楚,什么委托处理,回调函数,弄得我乌烟瘴气,不知所云。

  两年过去了,对知识的增长也让我明白了许多,当再次接触GUI的时候却不是在Java上,而是Matlab上,突然间发觉很多东西都是相同的,我们在做一件事情的时候,偏激一点的想法就是怎么样处理好这个东西,我在这里故意不说界面的问题,别见怪。

   怎么处理使我最关心的事情,很多书上提到了回调函数,把我们要处理的东西放到这个函数里,OK,我们放到了这个函数里面,那这个和我们的控件又是怎么联系起来的?如果把这个回调函数作为控件的一个属性,是不是很好理解,那它又是怎么知道我们所发出的动作,拖动,单击?

   当再次拿起Java的时候,我刚说的如果把这个回调函数作为一个属性?Java中让这些作为了控件的事件,而让另外一个对象对其监听,当然这个对象要注册的,要不控件又怎么和这个对象联系起来?

  这样一想,似乎一切都明白了,不知道正确与否?

    但是这个时候我不得不提一下句柄,这个是老师在讲授VC++的时候,我的VC++在我的手中算是报废了。但是我还是要说一下,尽管不是很懂,只是知道指针和句柄是有区别的,实例更不用说。

以下来自http://www.cppblog.com/redapple/archive/2006/05/29/7825.html

句柄是一种指向指针的指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这  
个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问对象。但是,如果您真的这样认为,那么您就大错特错了。我们知道,Windows是一 个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了。如果地址总是如此变化,我们该到哪里去找该对象呢?为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。Windows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。句柄地址(稳定)→记载着对象在内存中的地址→对象在内存中的地址(不稳定)→实际对象。但是,必须注意的是程序每次从新启动,系统不能保证分配给这个程序的句柄还是原来的那个句柄,而且绝大多数情况的确一样的。假如我们把进入电影院看电影看成 是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和每次电 影院售给我们的门票总是不同的一个座位是一样的道理。

    我在一本书上看过,相关东西放在了这个空间中,我是这样理解的实例(对象)就是我们New的时候系统给分配的一块内存区间,而地址(指针)就是指向这个内存的,书上一般都会给一幅图来说明的,上面的文章说的很清楚,对象是常常被移动的,如果我们能用一个东西和这个对象牢牢地捆绑在一起那就好办了,句柄就帮了这个忙。  

还是照猫画虎弄得 。
那么下面我们就来看看Matlab是如何简单、快速而友好地解决这问题的吧。

1.首先我们新建一个GUI文件:File/New/GUI,
选择Blank GUI(Default)
2.进入GUI开发环境以后添加两个编辑文本框,几个静态文本框,和一个按钮。
布置好各控件以后,我们就可以来为这些控件编写程序来实现两数相加的功能了。
3.我们先为数据1文本框添加代码;
点击图上f标识,选择edit1_Callback,光标便立刻移到下面这段代码的位置。
function edit1_Callback(hObject, eventdata, handles)
% hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit1 as text
% str2double(get(hObject,'String')) returns contents of edit1 as a double
然后在上面这段代码的下面插入如下代码:
%以字符串的形式来存储数据文本框1的内容. 如果字符串不是数字,则现实空白内容
input = str2num(get(hObject,'String'));
%检查输入是否为空. 如果为空,则默认显示为0
if (isempty(input))
     set(hObject,'String','0')
end
guidata(hObject, handles);
这段代码使得输入被严格限制,我们不能试图输入一个非数字。
4.为edit2_Callback添加同样一段代码
5 现在我们为计算按钮添加代码来实现把数据1和数据2相加的目的。
用3中同样的方法在m文件中找到pushbutton1_Callback代码段 如下;
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
在上面这段代码后添加以下代码;
a = get(handles.edit1,'String');b = get(handles.edit12,'String');% a and b are variables of Strings type, and need to be converted % to variables of Number type before they can be added together
total = str2num(a) + str2num(b);c = num2str(total);% need to convert the answer back into String type to display itset(handles.text1,'String',c);guidata(hObject, handles);
下面我们来对上面这段程序分析一下;
a = get(handles.edit1,'String'); b = get(handles.edit12,'String');
上面这行代码把用户输入的数据存入到变量a,变量b中;
% a,b是字符型变量,在计算两者相加之前需把他们转换为数字型
total = str2num(a) + str2num(b);
这段代码实现两数相加
c = num2str(total);
set(handles.text3,'String',c);
guidata(hObject, handles);
以上两行代码分别用来更新计算结果文本框和图形对象句柄,一般Callback回调函数都以guidata(hObject, handles);j结束以更新数据。

   问题:我在Callback的函数下用hObject不成功,不是说这个是和Callback所关联的handles,看来,控件自己的回调函数调用自己的属性,只用hObject.属性名   就可以了(中间一点)。

handles,是这个GUI界面的代号。应该是一个容器吧,可以通过它获取这个界面的所有信息。所以在控件自己的回调函数中,要获取或者设置别的控件的属性,就用  handles.控件Tag.属性 .

那么这个hObject是不是和handles.控件Tag是等价的,如果不是,那看意思又怎么这么相似,如果是的话,是不是重复了?
上一篇:Python Flask 简明教程(12)--Flask获取Ajax传输的JSON数据


下一篇:JavaWeb学习之路(43)–CSS之显示类型