[转载] 关于matlab GUI的一点心得
转载自 落落轻尘
[Fig文件方式,即使用菜单File->New->GUI来设计界面]
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中,
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];
保存在handles里面――首先,这是访问控件的常用方法,注意到Tag是唯一标识控件的属性,也就说,如果一个控件的Tag属性是a,那么,在fig
对应的m文件中,只要含有“handles”作为其输入参数的函数中,就可以使用handles.a对该控件进行访问。既然句柄(相当于其他语言中的指
针)已经拿到手了,就任由“宰割”了(例如设置属性、存取数据等就比较容易了);其次,可以利用这种方法把自定义的变量保存在handles里面进行存取,这在matlab帮助的Creating
a GUI with GUIDE一节中有具体介绍,不多说;
用全局变量的方法――这是我进行参数传递的常用方法,使用方法是:在两个函数体(当然可以是多个了,这里是主函数和子函数的意思)中使用前加入语句
“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
—— 这是该控件基本用法的一点提示
1.
当控件位置有重叠时,直接放置方式与程序描绘方式不兼容。直接放置方式是指在GUI设计窗口中放置axes控件,程序描绘方式是指在程序中利用plot、
subplot函数作图。经本人测试,在同一个fig文件中,先使用程序描绘方式把图形plot出来(此时直接放置的axes控件为不可见状态),后欲再
把直接放置的axes控件重新设置为可见状态时,如果通过这两种方式控制的axes位置有重叠,那么放置的axes控件句柄会莫名其妙消失,变成无效句
柄,即出现Invalid
handle的错误(尽管其handle是有值的)。所以,在交替采用这两种方式的时候,其位置不能发生重叠。――其根本原因应该是第5点所说的
有多个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'); 便可。
设置对象透明属性的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的一点心得的更多相关文章
- 转载:关于Matlab GUI的一些经验总结
去年做了一些关于Matlab GUI的程序,现在又要做相关的东西,回想起来,当时很多经验没有记录下来,现在回顾起来始终觉得不爽,所以从现在开始,一定要勤写记录. 从简单的例子说起吧. 创建Matlab ...
- matlab GUI工作原理
例如,用GUIDE创建名为ceshi的GUI程序,其m文件的主函数有如下形式.那么,打开该GUI时,它到底是怎么运行的呢?以下略作小结,欢迎大家补充 function varargout = cesh ...
- [学习一个] Matlab GUI 学习笔记 Ⅰ
Matlab GUI 学习笔记 Ⅰ 1. Foreword Matlab 是严格意义上的编程语言吗?曾经有人告诉我他是通过 Matlab 学会了面对对象编程,我是不信的,但这依然不妨碍它在特殊领域的强 ...
- Unity GUI(uGUI)使用心得与性能总结
Unity GUI(uGUI)使用心得与性能总结 作者 kingshijie 关注 2015.09.26 15:35 字数 3686 阅读 28031评论 10喜欢 49 背景和目的 小哈接触Unit ...
- Matlab GUI memo
有一段时间没写博客,一周4篇文章都坚持不下来,不知道写哪个方面的内容,写研究相关就怕论文查重查到,其他方面也没太多时间去学.还是花时间多学点其他方面.废话到此,很早就做过matlab gui相关,现在 ...
- MATLAB GUI之ABC
GUIDE 属性设置 name 更改名字 logo 在GUI的".m"文件中的OpeningFcn函数或者OutputFcn函数中添加以下代码: % 设置页面左上角的 LogoI ...
- 关于Matlab GUI的一些经验总结
注:此文来自转载,侵删去年做了一些关于Matlab GUI的程序,现在又要做相关的东西,回想起来,当时很多经验没有记录下来,现在回顾起来始终觉得不爽,所以从现在开始,一定要勤写记录. 从简单的例子说起 ...
- MATLAB地图工具箱学习心得(二)设计可变参数和位置拾取的“放大镜”式投影程序
最近刚好因为一些原因整理这方面的内容,所以还是把这篇鸽了一年多的博客顺手写出来了∠( ᐛ 」∠)_.因为是当时课程设计的一部分,程序上难免会有一些不足和bug,在这里将设计的思路分享给大家. 本篇博客 ...
- MATLAB地图工具箱学习心得(一)关于地图分带投影的拼接
关于matlab地图投影系列: MATLAB地图工具箱学习心得(二)设计可变参数和位置拾取的"放大镜"式投影程序 --- 本学期的地图投影课程已经结束了,这篇博客用于记录自己在学习 ...
随机推荐
- python包/模块路径
当Python执行import语句时,它会在一些路径中搜索Python模块和扩展模块.可以通过sys.path查看这些路径,比如: >>> import sys >>&g ...
- sqlserver中的全局变量总结
@@CONNECTIONS返回自上次启动 Microsoft? SQL Server? 以来连接或试图连接的次数.@@CPU_BUSY返回自上次启动 Microsoft? SQL Server? 以来 ...
- 浅谈malloc/free和new/delete 的区别
malloc和new的区别 malloc是库函数,需要包头文件才能成功运行编译:new是操作符(C++中的关键字),需要在C++的环境下使用. malloc既可以在C语言中使用也可以在C++中使用,n ...
- 解决mysql不能远程登入的问题
mysql远程不能登入,问题就在于当时设置的账号只限制本地访问,mysql默认也只是本地访问. 之前的设置: 通过命令行登录管理MySQL服务器(提示输入密码时直接回车): mysql> /us ...
- 面试题46:求1+2+ …… +n
题目:求1+2+…+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字以及条件判断语句(A?B:C). 通常求1+2+…+n除了用公式n(n+1)/2之外,无外 ...
- 两种方法设置nginx并发限制下面的白名单策略
前言: 今天,公司主站突然出现IDE创建应用没反应的问题,经过预发布环境.非代理环境下面的服务测试,均没有问题,定位问题出现在前端.而我们前端有两层代理,一是青松抗D系统,一是我们自己的nginx代理 ...
- Rookey.Frame之系统初始化
昨天介绍了数据库的配置,今天继续介绍系统的初始化功能:针对系统初始化在开发中也是很重要的一部分,它可以提前将相关数据提前自动初始化到系统中,同时也可以为上线测试提供方便,可以很方便进行系统测试演练,防 ...
- 【LOJ】#2275. 「JXOI2017」颜色
题解 我们枚举右端点判断合法的左端点有哪些 首先,记录一下右端点右边的点的pre,也就是这个数字前一个出现的位置,取所有小于枚举右端点r的值中最大的一个做为l,用优先队列维护即可,[l + 1,r]就 ...
- HDU - 2199 Can you solve this equation? 二分 简单题
Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ( ...
- 四、redis系列之主从复制与哨兵机制
1. 绪言 在现实应用环境中,出于数据容量.容灾.性能等因素的考虑,往往不会只使用一台服务器,而是使用集群的方式.Redis 中也有类似的维持一主多从的方式提高 Redis 集群的高可用性的方案,而其 ...