1、Matlab GUI编程技巧1. 如何使gui编的界面一运行就居中?方法一:a假如当前的figure的句柄是h,则在程序运行的刚开始,用这个命令, set(h,visible,off); %使h对应的图不可见.b 然后你再进行你的其它的操作,c最后,在程序的结尾部分,用这两个语句: movegui(h,center); %将这个图移到中央.详细用法参阅helpmovegui set(h,visible,on); %恢复其可见性.方法二:function figureMiddledfigure;set(0,units,pixels);set(gcf,units,pixels);screenrec
2、t=get(0,screensize);screenwidth=screenrect(3);screenheight=screenrect(4);figwidth=600;figheight=200;figposition=(screenwidth/2-figwidth/2) . (screenheight/2-figheight/2). figwidth figheight;set(gcf,position,figposition);2. 有关GUI实时显示的问题首先,用MATLAB做实时显示其效果并不是很好,主要原因就是它的速度慢,尤其是你的程序中出现循环时,速度更慢. 前几天,我也做了一
3、个实时显示的东西,我的做法如下: 1.建立一个图,如h=plot(x,y); set(h,erasemode,xor)%设置擦除方式. 2.建立一个死循环,不断的接受数据,并且不断的更新x,y 3.用这个指令set(h,xdata,x,ydata,y) ,使x,y的数据不断的得到更新. 4.用屏幕刷新指令drawnow进行刷新. 就这个方法就可以做到实时了.3. 关于参数传递关于参数传递主要有三种方法:1). 就是用定义全局变量的方法来实现,如globala,等这种用法,这种一般用在小程序中,因为如果全局变量太多的话,会造成系统混乱. 2). 应用对象的userdata属性,直接通过对象的us
4、erdata属性来进行各个callback之间的数据存取操作.首先把数据存到一个特定的对象中,然后在取出来,如下: set( ui_handle,userdata,value) value=get(ui_handle,userdata) 这种方法虽然简单,但是缺点是每个对象只能存取一个变量值. 3). 利用setappdata,getappdata,rmappdata函数来实现,这几个函数来进行数据传递是最有弹性的.使用方法和第二种方法类似.4. 怎么直接将下面一段.txt格式导到MATLAB中?用load命令 load e:dataccc.txt;我的文件是e盘data下的其实还有一个方法可
5、以导入,有没有试过textread呢5. 函数结构与参数传递1)最近简单整理了一下发过的东西,将大家比较困惑的两个问题,再强调一下。这个问题我也曾经想过很久很久。就是某个函数的子函数,可能具有复用性,而我又不想改变原来的函数,怎样才能调用这个子函数呢?那就是给每一个函数加一个壳。例如这个函数结构:function varargout = test_function( varargin ) % . if nargin = 0 创建界面。 即使不创建界面,也可以采用这种函数结构。figurehandle = test_generatefigurecontent; 初始化函数,可以用于创建初始化数据
6、test_initfiguecontent(figurehandle); if nargout > 0 varargout1 = figurehandle ; end elseif ischar( varargin1 ) try if nargout > 0 varargout1:nargout = feval( varargin: ) ; else feval( varargin: ) ; end catch disp( lasterr ) ; end end % - function figurehandle = test_generatefigurecontent; . h
7、andles = guihandles( figurehandle ); guidata( figurehandle, handles ) ; % - function test_initfiguecontent( h ) handles = guidata( h ) ; DefaultData = test_GetDefaultData ;. % -function DefaultData = test_GetDefaultData ;DefaultData.ParaName = height; width; ;DefaultData.ParaKanaName = 高度; 宽度; ;Defa
8、ultData.height = 20 ;DefaultData.width= 5 ;% - function test_Uicontrol_Callback( h ) ; handles = guidata( h ) ; . % return ;-如果你要得到test_function里面的默认数据,就可以在其他函数中使用如下调用方式就能够得到:DefaultData = test_function( test_GetDefaultData ) ;程序会通过这个转换器进入子函数:elseif ischar( varargin1 ) try if nargout > 0 varargou
9、t1:nargout = feval( varargin: ) ; else feval( varargin: ) ; end catch disp( lasterr ) ; end end2)关于参数传递1. 尽量在内存中提取:方法有三种: 采用function的varargin和varargout传送, 存在handle的ApplicationData中,保存在handles里面。当然还有其他方法。 2.存在硬盘上,采用save和load。 3.用全局变量,最次的办法,有时却是最好的办法。 关于nargin,nargout,varargin,varargoutnargin:输入参数的个数,
10、主要用于两个方面:判断输入参数的个数,如果输入参数个数不对,可以警告或其他处理;根据参数个数的不同可以做不同的处理。如: if nargin = 0 error; elseif nargin = 1 elseif nargin = 2 else warndlg( , ,modal) return ; end nargout:输出参数的个数,用法同上。 varargin:输入参数的总和,保存为cell结构。提取方式如下: A = varargin1 ; B = varargin2:end ; varargout 输出参数。见到的最常见的用法是: if nargout > 0 varargo
11、ut1 =figurehandle ; end3)关于handles: 实际上这个handles是MATLAB中GUI编程中最常用的一个句柄管理变量。 handles的生成:handles = guihandles( figurehandle );将figure中所有对象中“Tag”属性有值的句柄的handle采集在一起。handles是结构名,每个“Tag”域名里保持此对象的句柄。 handles的保存:guidata( figurehandle, handles );handles将保存在figure对象的“ApplicationData”的一个域名里。 handles的使用:handle
12、s = guidata( h );其中为figure中任意一个对象的句柄。 handles.SpeechSourceGui可能是一个figure的句柄,“userdata”是一个对象的属性,可以在其中存取任何数据。但是我不怎么用它,一则它只能存一个变量;二则它无法存入变量的名字,很难区分。4)关于fevalfeval,首先我们可以把它理解为一个函数转换器。执行到feval时,系统将首先寻找内部函数,如果没有找到,再尝试找外部函数。feval也是一个函数封装器,在执行时它能够调用某个函数;但是在编译时,又可以不将这个函数编译到当前模块中。feval还有一个很强大的功能,如果结合了这个函数结构,就
13、可以在函数外部调用一个函数的内部函数或子函数。5)关于setappdata,getappdatasetappdata,将数据保存在对象的“ApplicationData”属性中。getappdata,从对象的“ApplicationData”属性中提取数据,如果没有定义,就为空。setappdata和getappdata操作的对象,最好为figure_handle,便于管理和扩展。Matlab的高级编程和对象控制,将大量使用这两个函数。6)关于function_handlefunction_handle在matlab环境下还是可以用的,但是不能支持编译,也就是说无法脱离matlab环境安全运行
14、在构建程序时,一定要考虑到扩展性,有些在某些条件下属于技术缺陷的方法,尽量不要用。7)关于try.catch.end昨晚给他们做培训,for和if结构讲了一个小时,下次有时间整理一下。在函数结构里面用到了try.catch.end结构,这个东西虽然保险,但还是尽量少用。因为它屏蔽了很多警告信息,无法很好的调试程序。8)If与for流程的十种用法范群树 2005-11-8一、if语句1.常规用法:if 条件语句;endif 条件语句1;els语句2;endif 条件语句1;elseif 条件语句2;else语句3;end2.做循环使用:if num = 1语句1;endif num = 2语句
15、2;endif num = 3语句3;end3.组合条件:if find( strcmp( 字符串,集合 ) )语句1;else语句2;end条件 = 逻辑判断语句;if 条件语句1;end4.代码切换(注释):iflogical(0)语句段1;(永不执行)else语句段2;end5.if 语句段不平衡的一种处理方式:if条件少量语句段1;return ;else大量语句段2;end二、for语句1.常规用法:for num = 1 : 3语句;end2.特殊用法:TempIndex = 3: -1: 1for num = TempIndex语句;endTempIndex = 245for n
16、um = TempIndex语句;end3.作分支处理:for num = 1语句1;endfor num = 2语句2;endfor num =3语句3;end4.封存语句段:TempIndex = for num = TempIndex语句段;(永不执行)endfor num = 4:1语句段;(永不执行)end5.动态定义循环次数TempIndex = 4;(可以由语句动态定义)for num = TempIndex: 6语句;end6.循环的跳转for num = 1: 10语句1;if 条件continue;end语句2;end三、switch语句switch语句可以使用得很灵活:s
17、witch 变量名case 1语句1;case 2; 3语句2;case a语句3;case b; c语句4;otherwise语句5;end6. 关于Object句柄的获取通过 findobj 可以根据Object的属性来获取其句柄来进行其它操作,但对于手工加入的Object,如:用鼠标绘制的直线,或加入的文字框(用text或gtext加入的可以)好象不行,请问如何获取这些对象的句柄。有几个办法。关键在于使用findall,而不是findobj。 如果你只有一条线。也就是在matlab里用figure命令,然后用figure窗口工具栏的Insert line画一条线,那么可以这样获得所画线条
18、的句柄:hLine = findall(gcf, Type, Line);如果你已经在该figure里画了一些曲线,比如:x = 0:.01:20; y = x.*sin(x); hPlot = plot(x, y);然后在用Insert line画一条线,那么这时用hLines = findall(gcf, Type, Line)获得的就是这两条线。那么怎么去区分这两条线呢?有好几种办法: 1. 一般用工具栏手工加上去的线条的句柄的数值比用plot德句柄值大,也就是说上面hLines里比较大的那个数值就是对应于手工添加对象的句柄。但是可能不保险。 2。通常用手工添加的线条的数据点只有两个,即
19、起始点和终止点,而用plot等所画的线条其数据点数目比较多,所以可以通过判断数据点个数来找出手工钱家对象。numOfPts = length(get(hLines(i), Xdata); % 用循环遍历所有句柄3. 既然是手工添加,当然应该明白所添加线条的位置,所以可以通过判断该线条的起始点和终止点的坐标值来判断,这种方法适合于手工添加两条以上的线条。4。最佳方法就是:既然是手工添加,那么在添加线条以后,顺手用鼠标双击该线条,在出来的Property窗口,Info标签下面,给这个线条一个Tag,那么在程序里就可以通过这个tag来唯一的确定该对象:hMyLine = findall(gcf, T
20、ag, myLine);7. 如何把matlab的fig文件显示到GUI的axe上?可能需要按照实际情况具体分析、对待:*如果那个Figure的图形也是这个GUI产生的,那么可以尝试直接在那个AXES上画,也就是在画图之前,用axes命令把目标AXES设成当前axes。然后再画图。*如果无法控制那个Figure,那么可以使用copyobj命令把该Figure上的内容全部拷贝到目标AXES上。关于以上命令的具体用法,请参阅在线帮助。在GUI上添个AXES而后plot(axes的句柄,x,y)最好把axes放在一个panel上至于保存,给个土办法再弄个fig=figure(visible,off)
21、用copyobj将axes拷到fig上这个可以在你的GUI有多个AXES时使用如果对GUI基本内容有初步了解,请尝试:axes(haxesi)%haxesi为想设为当前轴的轴句柄。或者注意set中的currentaxes属性。即:找到该轴句柄并设为当前set(gcf,currentaxes,haxesi)如果实在GUI里面做多个轴,可以在handles句柄当中找到这个轴如果有多个轴,首先将你的轴的Tag修改为您认为方面的名称,比如说两个轴,分别叫myAs1和myAx2。这样的轴或者控件的句柄都可以在默认的handles结构当中直接找到。如果你想在 myAx1上面画图,可以用axes(handl
22、es.myAx1);这样的命令,将轴myAx1设置为当前坐标轴,然后画图。也可以用底层的画图命令,指定在某一个轴上画图。比如说line命令:t=linspace(0,2*pi,100)line(t,sin(t),parent,handles.myAx1)8. 关于M文件与simulink之间传递数据simulink模块与m文件之间的参数传递可以使用get_param和set_param来实现.具体如下:比如你有个simulink model 文件test.mdl,包含一个名字为SineWave的正弦发生器,你需要通过m文件设置它的采样时间。但是你不知道在test.mdl中,SineWave的采
23、样时间这个属性的名称,就可以用这个命令来得到:get_param(test/SineWave,ObjectParameters)语句运行后,有一部分为: SineType: 1x1 struct TimeSource: 1x1 struct Amplitude: 1x1 struct Bias: 1x1 struct Frequency: 1x1 struct Phase: 1x1 struct Samples: 1x1 struct Offset: 1x1 struct SampleTime: 1x1 struct VectorParams1D: 1x1 struct看到没,SampleTi
24、me就是它的采样时间。好了,这时候你就可以通过get_param(test/SineWave,SampleTime)来得到原来模块中正弦发生器的采样时间。同样,在m文件中你可以通过set_param(test/SineWave,SampleTime,Ts)来设置它的采样时间,其中Ts为要设置的采样时间。9. 问几个GUI的问题1,保存AXES的图 我用了Copypbj. 代码axes在panel上 fignew = figure(visible,off); copyobj(figold.axes,fignew); copyobj(figold.legend,fignew); position=
25、get(figold.legend,position); position=0.898-hposition(3) 0.90-hposition(4) hposition(3) hposition(4); set(fignew.legend,position,position); 见图一. 1.如何使legend格式对齐. 2.发现legend position居然以panel为基准。这样figure缩放后legend无法对齐 3.版内有人说用imwrite,我试了,图不清晰,是否我没主意细节? 我自己采取的措施是: 1.figure直接最大化,resize=off。 2.legend的posi
26、tion强制给2. figure最大化。google说 fig=figure(outerposition,get(0,screensize) 这个可行,但resize=off后,figure遮盖了底部任务栏 时候有别的好方法?试试看把Units改成normalized。10. 关于“uipushtool”无意中发现的,这个功能对于构建自己的工具条挺方便,不知道以前的版本有没有,现在我的系统里就7.3一个了,有知道的给说一声。谢谢!另外,今天来了兴致,索性继续搜索,又发现一个命令uiimport,可以实现GUI式的数据导入,类似于file-import data菜单,安装7.3的朋友有兴趣可以一
27、试,看来7.3还是满有点儿意思的.function tryoneclch = figure(ToolBar,none,menubar,none,numbertitle,off,. name,给GUI定制按钮);ht = uitoolbar(h);X1=imread(a1.jpg);X2=imread(a2.jpg);hpt1 = uipushtool(ht,CData,X1,TooltipString,改变图形色系到cool,. ClickedCallback,peaks;,colormap(cool);hpt2 = uipushtool(ht,CData,X2,TooltipString,改
28、变图形色系到hot,. ClickedCallback,peaks;,colormap(hot);11. 如何将计算结果保存到.txt文件中1 fop=fopen(d:test.txt,w+); %算一个a a=1; fprintf(fop,%fn,a); %再算一个a a=2; fprintf(fop,%fn,a); fclose(fop)2. 把所有的a存起来%A=a1 a2 .a=1:10;save d:test1.txt a -ASCII12. 使用摄像头连续采集、保存图像源程序写了一个在matlab2006上用摄像头连续采集、保存图像源程序。运行imaq_test.m文件后,弹出保存
29、对话框,指定一个存盘目录,选定保存格式(如.jpg),输入主文件名(如aqim),点击开始采集按钮,将以设定的频率采集图像,并以aqim1.jpg,aqim2.jpg.保存在选定的文件夹中。不知道有没有更好的实现方式,希望大家能给出新的简洁思路,谢谢。%保存为 imaq_test.mhfig=figure;hpush1=uicontrol(gcf,style,push,unit,normalized,.string,开始采集,.position,0.1 0.1 0.1 0.05,callback,imaq_cyc);haxis1=axes(unit,normalized,.position,0
30、3 0.3 0.5 0.5);%保存为 imaq_cyc.m%读取任一文件,识别其文件名、后缀名、所在路径filename, pathname, filterindex = uiputfile( . *.jpg;*.bmp;*.tif;*.png, All PHOTO Files (*.jpg;*.bmp;*.tif;*.png); *.jpg,jpg-files (*.jpg); . *.bmp,bmp-files (*.bmp); . *.tif,tif-files (*.tif); . *.png,png-files (*.png); . *.*,All Files (*.*), .
31、Save as);if isequal(filename,0) | isequal(pathname,0) h=msgbox(你按下了取消键!,Title,custom,hot(64); else%确定存盘时的主文件名、后缀名filelen=length(filename);for k=1:filelen;if filename(k)=.;dotnum=k;end;k=k+1;end;insuffix= filename(dotnum:end);infname=filename(1:dotnum-1);%确定存盘时的主文件名、后缀名end%循环采集、保存图像vid=videoinput(win
32、video);imaqnum=10; %采集帧数for k=1:imaqnum;start(vid);aqdata1=getdata(vid,1);%先保存、再显示fullpath=pathname,infname,num2str(k),insuffix; %保存路径imwrite(aqdata1,fullpath);%不知道此处为何不能带上Quality参数imshow(aqdata1);pause(2); %采集频率2s/次k=k+1;end%循环采集、保存图像13. gui中的axes图形保存问题%保存为 savetest.mhfig=figure;hpush1=uicontrol(gc
33、f,style,push,unit,normalized,.string,saveas,.position,0.1 0.1 0.1 0.05,callback,savefile);haxis1=axes(unit,normalized,.position,0.3 0.3 0.5 0.5);imshow(imread(rice.tif);%保存为 savefile.mhimage=findobj(gcf,type,image);riceimg=get(himage,CData);filename, pathname, filterindex = uiputfile( . *.jpg;*.bmp;
34、tif;*.png, All PHOTO Files (*.jpg;*.bmp;*.tif;*.png); *.jpg,jpg-files (*.jpg); . *.bmp,bmp-files (*.bmp); . *.tif,tif-files (*.tif); . *.png,png-files (*.png); . *.*,All Files (*.*), . Save as);fullpath=pathname,filename;imwrite(riceimg,fullpath,quality,100);运行savetest , 点击界面上的saveas ,选则路径、确定文件名、类
35、型,保存14. Figure窗口辅助操作函数支持中文Help for C language mex function -mexwndop mexwndop(window_title, operation)Do some operations to a window. Created By SCIE ( for cwit and all other friends who need it ) Arguments window_title: A row vector of string ,the title of a window (a figure or dialog) ,can include
36、 Chinese characters. operation: A row vector of string ,the operation made to the window whos title is window_title. The second argument operation can has such values: 1.topmost Make the window always on top of other windows 2.notopmostCancel the property of aways on top of the window. 3.maximize Ma
37、ximize the window 4.minimize Minimize the window 5.restore Reset the size and position of the window and show it 6.hide Hide the window 7.show Show the window invisible,no effects on a visible window Example: figure(NumberTitle,off,name,中文标题); mexwndop(中文标题,maximize); 在使用中发现Bug或有任何问题请及时通知我。15. gui编程
38、是否可以实现选项卡的功能?标签视图代码,基于uipanel,可以在其上绘图,必需在7.0下运行,视图支持resize(resize时还有bug希望大家帮我调试)。函数名tabfig,视图的视觉效果没有都写进成函数参数,可以在代码中改,代码中有说明。-调用格式:hfig, sheetPos = tabfig(. create,strings,tabDims,callback,sheetDims,offsets,default_page)callback 参数为每次按tab时调用的函数名,传给它的参数为: 1) tabcallbk - 标识 tabcallbk 2) pressedTab - 选择tab的字符串 3) pressedTabNum - 选择tab号码 4) previousTab - 上一个选择的tab的字符串 5) previousTabNum- 上一个选择的tab的号码 6) hfig - 图形句柄其他参数说明见help tabfig-调用例子:strings=标签1,标签2,标签3,标签4;tabDims1=80 50 50 50;tabDims2=16;callback=tabchange;sheetDims=800400;offsets=3 5 5 3;d