转载自 落落轻尘

[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 reserved - to be
defined in a future version of MATLAB
% handles structure with
handles and user data (see GUIDATA)
% Hints: contents =
get(hObject,'String') returns listbox1 contents as cell array ——
这是该控件基本用法的一点提示
%
contents{get(hObject,'Value')} returns selected item from listbox1
—— 这是该控件基本用法的一点提示

最后,介绍一下我在使用的过程中发现的一些问题或者技巧(真的只有一点点而已,希望以后可以不断补充拉,这些技巧对m文件方式的GUI也适用):

1.
当控件位置有重叠时,直接放置方式与程序描绘方式不兼容。直接放置方式是指在GUI设计窗口中放置axes控件,程序描绘方式是指在程序中利用plot、
subplot函数作图。经本人测试,在同一个fig文件中,先使用程序描绘方式把图形plot出来(此时直接放置的axes控件为不可见状态),后欲再
把直接放置的axes控件重新设置为可见状态时,如果通过这两种方式控制的axes位置有重叠,那么放置的axes控件句柄会莫名其妙消失,变成无效句
柄,即出现Invalid
handle的错误(尽管其handle是有值的)。所以,在交替采用这两种方式的时候,其位置不能发生重叠。――其根本原因应该是第5点所说的

2.
有多个axes控件时,可以用axes(handles.haxis)来选择切换,这个方法比plot(x,y,’parent’,haxis)更加灵
活,应该不算原创(因为在精通GUI一书上有介绍),但是在我读此书之前就一直使用到现在。具体来说,在fig文件方式的GUI中,假设你的axes控件
的tag属性值为hA,则在画图前使用axes(handles.hA);就可以指定在这个axes上面作图;在m文件方式的GUI中,假设你是通过
hA=axes(...);创建这个控件的,那么使用plot(x,y,'parent',hA);语句就可以指定在这个axes上面作图。其他控件也类
似,以
Edit 控件为例,首先给 edit1 增加一个Tag属性,即:H_edit1=……'Tag','edit1'……; ,然后使用
set(findobj('Tag','edit1'),'string','1234'); 便可。

3.
设置对象透明属性的alpha(.5)语句会影响其他对象的可见性设置,也就是说,当fig窗口中某个对象(我的例子是axes对象)使用了alpha语
句设置其透明度之后,就不能对fig窗口中其他对象设置Visible属性为off了,此时off值是失效的,解决办法是对其他对象设置Enable属性
来近似达到需要的效果。

【以下转自newseee】
4.
设计GUI,mailab版本越高越好,bug少,功能全面。比如
uigeifile(还是uigetdir?记不清了。)在R12中就不支持。初始化时,加上版本判断。
5.
axes物件不能放到其它物件之上!
6.
axes没有Callback,但是可以在上面放一张图(image),可以有Callback。

7. windows和linux下
GUI会看起来不一样,为了兼容,字体改成default,Unit
的单位要用characters。 
8.
动态图形是循环画出来的。打开figure的DoubleBuffer到on,可以避免图形的闪烁。记得要用axes(h)。因为每plot一次,坐标系就刷新了。人不能踩进同一条河里。

9. matlab r13
有bug,linux下submenu不能动态更新,能删除,不能添加。我的解决办法是在callback中把GUI都关闭,然后更新submenu
(在主函数中 function varargout = untitled_OutputFcn(hObject, eventdata,
handles) 这一行下面添加,此时窗口还没有创建。),然后重新打开gui。

[m文件方式设计界面]
这种方式的入门最好根据自己的需要,下载一些具体例子作为参考(例如振动
或仿真等论坛上一些牛人发的帖子),结合手头上的任务(或者兴趣)来学。与上面的fig文件方式相比,这种方式可以夸不同的matlab平台使用,不必考
虑兼容性问题(当然了,要满足一个前提:要该平台的语法或命令支持才行,例如&&在6.5版本无效,也就是说,如果你的程序是用7.0以
上版本的matlab编写,但是希望程序可以在6.5版本中运行,那么在编写条件判断语句时只能使用&),但是换来的代价是所有控件的创建和布
局、事件的响应函数入口等等都需要自己用代码来实现,因此比fig文件方式要困难一点。当然,你可以下载别人写好的界面来做修改。一般来说,如果是用来内
部调试、测试的话,用fig方式比较好,但是如果用来向外发布的话,还是m文件方式比较通用一点(虽然可以打包来换取多一点的通用性,但你总不能带着
100多m的MCRInstaller文件到处走吧?2006b是100多m,2006a好像是60多m,记不清了)。

1.
建立控件时,直接采用“'属性名','属性值'”的方式(如'CallBack','delete(gcbf);clear
all;abc()')将导致程序不能调试到达其响应函数(貌似调用自己时不能,调用其他函数可以,没有完全测试,呵呵),
解决方法是使用消息传递,即'CallBack’, @Action,然后写:
Function
Action(hObject,eventdata,handles)
delete(gcbf);
clear all;
abc();
2.
实现进度条有两种方式(可能不止):waitbar方式和uicontrol方式,后者可以使用两个edit控件,或者使用axes控件加上line函数
生成,但是无论哪种方式,如果每次循环都刷新一下,那么当循环总次数很大时(如几十万次),运行速度会减慢,建议每隔一段距离(step)刷新一次,这样
可以加快运行速度。例如:

if (i - 100*k/N) <=
1e-003
waitbar(k/N);
i = i + step;
end
其中i是控制进度条在何处刷新,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) <=
1e-003
set(e2,'position',[0.3525,0.6,0.015,0.01+0.24*i/n]);

drawnow;
ii = ii + 1;
end
end【附录】转自cwit兄:
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的设计界面
(菜单操作:FileàNewàGUIàOpen
Existing GUI,打开 fig 文件。

[转载] 关于matlab GUI的一点心得的更多相关文章

  1. 转载:关于Matlab GUI的一些经验总结

    去年做了一些关于Matlab GUI的程序,现在又要做相关的东西,回想起来,当时很多经验没有记录下来,现在回顾起来始终觉得不爽,所以从现在开始,一定要勤写记录. 从简单的例子说起吧. 创建Matlab ...

  2. matlab GUI工作原理

    例如,用GUIDE创建名为ceshi的GUI程序,其m文件的主函数有如下形式.那么,打开该GUI时,它到底是怎么运行的呢?以下略作小结,欢迎大家补充 function varargout = cesh ...

  3. [学习一个] Matlab GUI 学习笔记 Ⅰ

    Matlab GUI 学习笔记 Ⅰ 1. Foreword Matlab 是严格意义上的编程语言吗?曾经有人告诉我他是通过 Matlab 学会了面对对象编程,我是不信的,但这依然不妨碍它在特殊领域的强 ...

  4. Unity GUI(uGUI)使用心得与性能总结

    Unity GUI(uGUI)使用心得与性能总结 作者 kingshijie 关注 2015.09.26 15:35 字数 3686 阅读 28031评论 10喜欢 49 背景和目的 小哈接触Unit ...

  5. Matlab GUI memo

    有一段时间没写博客,一周4篇文章都坚持不下来,不知道写哪个方面的内容,写研究相关就怕论文查重查到,其他方面也没太多时间去学.还是花时间多学点其他方面.废话到此,很早就做过matlab gui相关,现在 ...

  6. MATLAB GUI之ABC

    GUIDE 属性设置 name 更改名字 logo 在GUI的".m"文件中的OpeningFcn函数或者OutputFcn函数中添加以下代码: % 设置页面左上角的 LogoI ...

  7. 关于Matlab GUI的一些经验总结

    注:此文来自转载,侵删去年做了一些关于Matlab GUI的程序,现在又要做相关的东西,回想起来,当时很多经验没有记录下来,现在回顾起来始终觉得不爽,所以从现在开始,一定要勤写记录. 从简单的例子说起 ...

  8. MATLAB地图工具箱学习心得(二)设计可变参数和位置拾取的“放大镜”式投影程序

    最近刚好因为一些原因整理这方面的内容,所以还是把这篇鸽了一年多的博客顺手写出来了∠( ᐛ 」∠)_.因为是当时课程设计的一部分,程序上难免会有一些不足和bug,在这里将设计的思路分享给大家. 本篇博客 ...

  9. MATLAB地图工具箱学习心得(一)关于地图分带投影的拼接

    关于matlab地图投影系列: MATLAB地图工具箱学习心得(二)设计可变参数和位置拾取的"放大镜"式投影程序 --- 本学期的地图投影课程已经结束了,这篇博客用于记录自己在学习 ...

随机推荐

  1. OA项目Spring.Net代替抽象工厂(三)

    Servrvice层的代码: <?xml version="1.0" encoding="utf-8" ?> <objects xmlns=& ...

  2. Java小实验之数据转换

    看到有人问如图的程序,就去写了几行代码,顺便复习一下条件语句和ASCII码 import java.util.Scanner; public class test1 { public static v ...

  3. 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) M - Unsatisfying 2-Sat

    题目大意:给你 m 个式子, 问你最少再添加多少式子能使没有任何一种赋值方式使全部的式子为真. 并且在你给的式子中不能有非. 思路:根据题目给的m个式子可以建出2-Sat的图, 现在问你最少加多少个边 ...

  4. 线段树-最小逆序数hdu1394

    title: 线段树-最小逆序数 date: 2018-10-12 17:19:16 tags: acm 算法 刷题 categories: ACM-线段树 概述 这是一道简单的线段树的题,,,当然还 ...

  5. In 和Exists

    1.exist,not exist一般都是与子查询一起使用. In可以与子查询一起使用,也可以直接in (a,b.....) 2.exist会针对子查询的表使用索引. not exist会对主子查询都 ...

  6. NetCore控制台实现自定义CommandLine功能

    命令行科普: 例如输入: trans 123 456 789 -r 123 -r 789上面例子中:trans是Command,123 456 789是CommandArgument,-r之后的都是C ...

  7. modernizr.js的介绍和使用

    原文链接:https://www.cnblogs.com/-simon/p/5907053.html Modernizr帮助我们检测浏览器是否实现了某个feature,如果实现了那么开发人员就可以充分 ...

  8. Jquery的方法(一)

    一.文档操作1.内部插入:append(),appendTo(),prepend():2.外部插入:after(),before():3.删除操作:remove(),empty():4.克隆操作:cl ...

  9. Django框架(一)-Django初识

    Django初识 一.Web框架本质—自己实现Web框架 1.所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端 import socket sk = sock ...

  10. linux中的文件编码及编码修改

    查看文件编码 在Linux中查看文件编码可以通过以下几种方式: 1.在Vim中可以直接查看文件编码 :set fileencoding 即可显示文件编码格式. 如果你只是想查看其它编码格式的文件或者想 ...