关于GUI的一点心得体会_matlabgui毕业设计
关于GUI的一点心得体会由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“matlabgui毕业设计”。
[Fig文件方式,即使用菜单File->New->GUI来设计界面] 首先值得注意的是,在低版本matlab上 制作的含GUI的m文件一般不能在高版本的matlab上面运行,但是从7.0版开始改进了一点,我试过 6.5版的含GUI的m文件可以在 7.0版上运行,但如果在7.0版上面修改过.fig文件,那么就不能回到6.5版上运行了(显示一堆错误,我没看懂,不知道能否通过修改使之重新可在 6.5版上运行,呵呵),而在7.0版上制作的含GUI的m文件就完全不能放到6.5版上运行了(也是同样的错误)。这可能是因为matlab各版本在 GUI上改动较大,所以都不支持向下兼容。也许兼容性差是使用GUI编写程序的最大麻烦。
其次,说说使用GUI的好处。不知道是否承袭了VC or BCB的习惯,我比较喜欢编写完程序后按快捷键运行(此时会自动保存m文件),但是,对于程序有输入参数的 时候,如果不采用GUI方式,这显然是行不通的――当然了,可以在command window按“向上”键然后重新改写你想要的参数。对于一些较大型的程序,正因为我比较偏向于按F5运行程序,所以我会选择使用GUI方式。不过GUI 方式的好处就远不止于此了,它可以把几个功能相关的模块集中起来,使得不需要重新关闭、运行就能得到不同的结果,便于比较;可以减少figure满天飞的现象,这在matlab中尤为明显;便于交互式地观看不同的数据,例如在我处理的fMRI问题中,希望观看每个三维点对应的时间序列,这时候需要提供交互式的选择„„不过,尽管GUI有很多好处,但是其缺点也是有的,除了上面提到的兼容性(移植性)以外,要管理、维护一个GUI界面也是比较麻烦的,相信有其他语言的界面设计经验的朋友也知道这点。
再 者,对GUI问题,说说我的一点经验吧。其实,matlab已经在这方面改进了不少,从控件的增加和教程的学习都可以看出来。例如6.5版本是没有 Panel和Button Group这两个控件的,在2006a版本中就新增了这两个控件(这个好像7.0版就有了,不确定);教程方面,也使用了最为直观的视频教学方式,建议新手看看Creating a GUI with GUIDE 和Creating Graphical User Interfaces两节。所以,操作上的细节我就不多讲了,自己摸索一下就ok了。至于编程时最为关键的参数传递问题,可以参考本论坛或者仿真论坛上面的“函数结构与参数传递”一文,作者整理得较完整,不过有点难懂。这里我简单说一下吧:
[转cwit]关于参数传递的方法:
1.在内存中提取:① 采用function的varargin和varargout传送,② 存在handle的ApplicationData中,③保存在handles里面。当然还有其他方法; 2.存在硬盘上,采用save和load;
3.用全局变量,最次的办法,有时却是最好的办法;
我想,对于这里处理的GUI问题,一般不会用到save和load命令(要 从mat文件读取数据初始化或者把数据存储到mat文件中例外),“function的varargin和varargout传送”的方法也不较少使用(因为对于控件的回调函数,matlab规定了输入参数为“hObject, eventdata, handles, varargin”,且一般没有返回值,所以不同于自定义的函数),所以剩下的方法就只有三种了: 1.存在handle的ApplicationData中――利用setappdata函数将数据保存在对象的“ApplicationData”属性中,利 用getappdata函数从对象的“ApplicationData”属性中提取数据,如果没有定义,就为空。例如,假设figure的tag属性是 figure1,则setappdata(handles.figure1,’A’,A)就可以把变量A存放到figure1的 “ApplicationData”属性中,名字为A,而B = getappdata(handles.figure1,’A’)就可以把figure1的“ApplicationData”属性中名字为A的变量赋给 B。setappdata和getappdata操作的对象,最好为figure_handle,便于管理和扩展。Matlab的高级编程和对象控制,将 大量使用这两个函数[转自cwit];
2.保存在handles里面――首先,这是访问控件的常用方法,注意到Tag是唯一标识控件的属性,也就说,如果一个控件的Tag属性是a,那么,在fig 对应的m文件中,只要含有“handles”作为其输入参数的函数中,就可以使用handles.a对该控件进行访问。既然句柄(相当于其他语言中的指 针)已经拿到手了,就任由“宰割”了(例如设置属性、存取数据等就比较容易了);其次,可以利用这种方法把自定义的变量保存在handles里面进行存取,这在matlab帮助的Creating a GUI with GUIDE一节中有具体介绍,不多说;
3.用全局变量的方法――这是我进行参数传递的常用方法,使用方法是:在两个函数体(当然可以是多个了,这里是主函数和子函数的意思)中使用前加入语句 “global A”,其中A是多个函数需要传递的变量名,多个变量用空格格开,句末不需要加分号。这种方法由于存放在硬盘上,存取速度会减慢,但是如果变量个数不多、或 者对该变量引用的函数不多,可以考虑用此办法(我尚未能领会cwit兄所说“最次的办法,有时却是最好的办法”之含义)。
至于其他有关GUI命令、控件属性和图形属性可以参考matlab的帮助,或者参考“GUI命令大全”、《精通GUI图形界面编程》(这两个本论坛有)、“Matlab图形图像属性”、“GUI.rtf”(这两个参见附件,后者下载后手动修改一下后缀名)。实际上,用得比较多的控件属性不外乎以下几种(高手例外):
Visible属性,例如axes、edit、button等,格式:set(handles.***, ‘Visible’, ‘on’);或者set(handles.***, ‘Visible’, ‘off’);
String属性,例如edit、text等,格式:str=get(handles.***, ‘String’)或set(handles.***,’String’,str);Enable属性,例如edit、button、text等,格式:set(handles.***, ‘Enable’, ‘on’);或者set(handles.***, ‘Enable’, ‘off’);
Value属性,例如radio button、check box等,格式:a=get(handles.***, ‘Value’)或set(handles.***,’Value’,1);或set(handles.***,’Value’,0);
留意一下响应函数的注释部分,有时候会得到提示的。例如,我的 matlab 2007a 中,在设计界面上增加了 listbox 控件后,m 文件的对应回调函数处显示如下:
%---Executes on selection change in listbox1.function listbox1_Callback(hObject, eventdata, handles)% hObject handle to listbox1(see GCBO)% eventdata reserved100*k/N)
使用 uicontrol 方式实现进度条的示例: 复制内容到剪贴板 代码: figure;e1 = uicontrol(gcf,'style','edit','BackgroundColor','w',...'unit','normalized','position',[0.35,0.6,0.02,0.25]);e2 = uicontrol(gcf,'style','edit','BackgroundColor','r',...'unit','normalized','position',[0.3525,0.6,0.015,0.01]);drawnow;n = 1000;ii = 1;for i = 1:0.01:n if(ii-100*i/n)
m文件与fig文件创建figure的十大差异——用代码写figure,并不是麻烦。如果你习惯了,或者熟悉了,会发现用代码实现guide编程,比GUI方便很多,功能也很强大。用m文件实现guide编程,相比GUI编程有几大差异: 1.代码可复用,节省成本;
2.GUI不能灵活创建uimenu,并且不能编辑其所有属性; 3.GUI还没有实现创建uitoolbox; 4.GUI不能创建所有axes的子对象;
5.写界面也有一些算法,在GUI中无法实现。而用m文件就可以实现在不同窗口尺寸下给对象以合适的位置; 6.m文件可以生成非常复杂的界面;
7.采用GUI编程,代码编译后依赖于*.fig文件; 8.m文件可以实现组件;
9.m文件创建的对象,可以方便的在handle中存取数据; 10.m文件可以将创建对象代码与动作执行代码很好的结合起来。
【注】关于两种方式的运行:
对于fig文件方式:fig文件记录的是控件的布局和属性等资源信息,m文件记录的是控件的响应消息(这是个人理解,更准确的介绍请参阅有关GUI的书籍,我懒得去查了,呵呵),两者缺一不可。所以,不能通过打开fig文件(如菜单中的Open命令)来运行该GUI,这种方式的运行方法有两种:打开该GUI对应的m文件,然后像普通m文件那样运行;打开该GUI的设计界面(菜单操作:FileNewGUIOpen Existing GUI,打开 fig 文件),然后点击设计界面工具栏上的那个像箭头一样的按钮
对于m文件方式:像普通m文件那样运行就可以了
先建立两个GUI,一个名为guidata1.fig guidata2.fig,它们的tag属性也分别为guidata1,guidata2。然后在guidata1.m中的opening function中加入下列语句:
setappdata(handles.guidata1,'Sai',1);
在guidata2.m中的opening function 中写入下列语句:
setappdata(handles.guidata2,'Sai',2);
下面我们分别在guidata1.fig guidata2.fig中放一个按钮和静态文本。接下来,在guidata1.m的按钮中加入下列程序:
guidata21=findobj('Tag','guidata2');if isempty(guidata21),errordlg('Not Open guidata2.fig','Error');
guidata22=guidata2();
Sai=getappdata(guidata22.guidata2,'Sai');
set(handles.text1,'String',num2str(Sai));else
guidata22=guihandles(guidata2);
Sai=getappdata(guidata22.guidata2,'Sai');
set(handles.text1,'String',num2str(Sai));end
在guidata2.m中的按钮中加入下列程序:
guidata12=findobj('Tag','guidata1');%查看guidata1.fig是否打开 if isempty(guidata12), %如果没有打开
guidata11=guidata1();%打开guidata1.fig,并且把句柄给guidata11
guidata11=guihandles(guidata11);%把guidata11转为可用的gui句柄
Sai=getappdata(guidata11.guidata1,'Sai');%读取句柄guidata11中的名为Sai的变量值,可以和其%%%%%%%%%opening function 中的对比setappdata(handles.guidata1,'Sai',1)
set(handles.text1,'String',num2str(Sai));else
guidata11=guihandles(guidata1);
Sai=getappdata(guidata11.guidata1,'Sai');
set(handles.text1,'String',num2str(Sai));end
然后随便打开某个fig文件,比如打开guidata1.fig,然后点其中的按钮,可以看到下面的静态文本上显示2,那么这个自然是从guidata2.fig中读出来的。而且会自动打开guidata2.fig.这里其实是用findobj首先看是否已经打开guidata1,如果没有打开,则打开,并将句柄转化为gui句柄。我在opening function 中是将名为Sai,值为1的变量存在了figure中,其实也可以存在其他控件中,比如在按钮上加一个应用程序数据其名为Sai,值为1,那么可以这么写 setappdata(handles.pushbutton1,'Sai',1),然后随时我们都可以通过getappdata setappdata来获取或设置其值。
而这里我推荐用这两个命令,如果你用handles来共享数据的话,一是他可能会被程序的其他控件改变,二是它容易和引用控件时想混淆。