收藏 分销(赏)

MatlabGUI编程技巧.doc

上传人:二*** 文档编号:4768030 上传时间:2024-10-12 格式:DOC 页数:35 大小:288KB
下载 相关 举报
MatlabGUI编程技巧.doc_第1页
第1页 / 共35页
本文档共35页,全文阅读请下载到手机保存,查看更方便
资源描述
Matlab GUI编程技巧 1. 如何使gui编的界面一运行就居中? 方法一: a>假如当前的figure的句柄是h,则在程序运行的刚开始,用这个命令,                 set(h,'visible','off');           %使h对应的图不可见. b> 然后你再进行你的其它的操作, c>最后,在程序的结尾部分,用这两个语句:                      movegui(h,'center');   %将这个图移到中央.详细用法参阅help  movegui                      set(h,'visible','on');     %恢复其可见性. 方法二: function figureMiddled figure; set(0,'units','pixels'); set(gcf,'units','pixels'); screenrect=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做实时显示其效果并不是很好,主要原因就是它的速度慢,尤其是你的程序中出现循环时,速度更慢.    前几天,我也做了一个实时显示的东西,我的做法如下:            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). 就是用定义全局变量的方法来实现,如global  a,等这种用法,这种一般用在小程序中,因为如果全局变量太多的话,会造成系统混乱.    2). 应用对象的userdata属性,直接通过对象的userdata属性来进行各个callback之间的数据存取操作.首先把数据存到一个特定的对象中,然后在取出来,如下:          >> set( 'ui_handle','userdata',value)          >>value=get('ui_handle','userdata')       这种方法虽然简单,但是缺点是每个对象只能存取一个变量值.    3). 利用setappdata,getappdata,rmappdata函数来实现,这几个函数来进行数据传递是最有弹性的.使用方法和第二种方法类似. 4. 怎么直接将下面一段.txt格式导到MATLAB中? 用load命令 load e:\data\ccc.txt;我的文件是e盘data下的 其实还有一个方法可以导入,有没有试过textread呢 5. 函数结构与参数传递 1) 最近简单整理了一下发过的东西,将大家比较困惑的两个问题,再强调一下。 这个问题我也曾经想过很久很久。就是某个函数的子函数,可能具有复用性,而我又不想改变原来的函数,怎样才能调用这个子函数呢?那就是给每一个函数加一个壳。例如这个函数结构: function varargout = test_function( varargin ) % .................... if nargin == 0 % 创建界面。 % 即使不创建界面,也可以采用这种函数结构。 figurehandle = test_generatefigurecontent; % 初始化函数,可以用于创建初始化数据。 test_initfiguecontent(figurehandle); if nargout > 0 varargout{1} = figurehandle ; end elseif ischar( varargin{1} ) try if nargout > 0 [varargout{1:nargout}] = feval( varargin{:} ) ; else feval( varargin{:} ) ; end catch disp( lasterr ) ; end end % ------------------------------------------------------------------------- function figurehandle = test_generatefigurecontent; ..................................... handles = 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 = {'高度'; '宽度';} ; DefaultData.height = 20 ; DefaultData.width= 5 ; % -------------------------------------------------- function test_Uicontrol_Callback( h ) ; handles = guidata( h ) ; ........................................ % return ; ------------------------------------------------------------------------- 如果你要得到test_function里面的默认数据,就可以在其他函数中使用如下调用方式就能够得到: DefaultData = test_function( 'test_GetDefaultData' ) ; 程序会通过这个转换器进入子函数: elseif ischar( varargin{1} ) try if nargout > 0 [varargout{1:nargout}] = feval( varargin{:} ) ; else feval( varargin{:} ) ; end catch disp( lasterr ) ; end end 2) 关于参数传递 1. 尽量在内存中提取:方法有三种:① 采用function的varargin和varargout传送,② 存在handle的ApplicationData中,③保存在handles里面。当然还有其他方法。 2.存在硬盘上,采用save和load。 3.用全局变量,最次的办法,有时却是最好的办法。 关于nargin,nargout,varargin,varargout nargin:输入参数的个数,主要用于两个方面:①判断输入参数的个数,如果输入参数个数不对,可以警告或其他处理;②根据参数个数的不同可以做不同的处理。如: if nargin == 0 error; elseif nargin == 1 ………… elseif nargin == 2 ………… else warndlg( '……‘, ’‘,‘modal') return ; end nargout:输出参数的个数,用法同上。 varargin:输入参数的总和,保存为cell结构。提取方式如下: A = varargin{1} ; B = varargin{2:end} ; varargout 输出参数。见到的最常见的用法是: if nargout > 0 varargout{1} =figurehandle ; end 3) 关于handles: 实际上这个handles是MATLAB中GUI编程中最常用的一个句柄管理变量。 handles的生成:handles = guihandles( figurehandle );将figure中所有对象中“Tag”属性有值的句柄的handle采集在一起。handles是结构名,每个“Tag”域名里保持此对象的句柄。 handles的保存:guidata( figurehandle, handles );handles将保存在figure对象的“ApplicationData”的一个域名里。 handles的使用:handles = guidata( h );其中为figure中任意一个对象的句柄。 handles.SpeechSourceGui可能是一个figure的句柄,“userdata”是一个对象的属性,可以在其中存取任何数据。但是我不怎么用它,一则它只能存一个变量;二则它无法存入变量的名字,很难区分。 4) 关于feval feval,首先我们可以把它理解为一个函数转换器。执行到feval时,系统将首先寻找内部函数,如果没有找到,再尝试找外部函数。 feval也是一个函数封装器,在执行时它能够调用某个函数;但是在编译时,又可以不将这个函数编译到当前模块中。 feval还有一个很强大的功能,如果结合了这个函数结构,就可以在函数外部调用一个函数的内部函数或子函数。 5) 关于setappdata,getappdata setappdata,将数据保存在对象的“ApplicationData”属性中。 getappdata,从对象的“ApplicationData”属性中提取数据,如果没有定义,就为空。 setappdata和getappdata操作的对象,最好为figure_handle,便于管理和扩展。 Matlab的高级编程和对象控制,将大量使用这两个函数。 6) 关于function_handle function_handle在matlab环境下还是可以用的,但是不能支持编译,也就是说无法脱离matlab环境安全运行。在构建程序时,一定要考虑到扩展性,有些在某些条件下属于技术缺陷的方法,尽量不要用。 7) 关于try...catch...end 昨晚给他们做培训,for和if结构讲了一个小时,下次有时间整理一下。 在函数结构里面用到了try...catch...end结构,这个东西虽然保险,但还是尽量少用。因为它屏蔽了很多警告信息,无法很好的调试程序。 8) If与for流程的十种用法 范群树   2005-11-8 一、if语句 1.常规用法: if 条件   语句; end if 条件   语句1; els   语句2; end if 条件   语句1; elseif 条件   语句2; else   语句3; end 2. 做循环使用: if num == 1   语句1; end if num == 2   语句2; end if num == 3   语句3; end 3. 组合条件: if find( strcmp( 字符串,集合 ) )   语句1; else   语句2; end 条件 = 逻辑判断语句; if 条件   语句1; end 4. 代码切换(注释): if  logical(0)   语句段1;(永不执行) else   语句段2; end 5. if 语句段不平衡的一种处理方式: if  条件   少量语句段1;   return ; else   大量语句段2; end 二、 for语句 1. 常规用法: for num = [1 : 3]   语句; end 2. 特殊用法: TempIndex = [3: -1: 1] for num = TempIndex   语句; end TempIndex = [2  4  5] for num = TempIndex   语句; end 3. 作分支处理: for num = 1   语句1; end for num = 2   语句2; end for num =3   语句3; end 4. 封存语句段: TempIndex = [] for num = TempIndex   语句段;(永不执行) end for num = [4:1]   语句段;(永不执行) end 5. 动态定义循环次数 TempIndex = 4;(可以由语句动态定义) for num = TempIndex: 6   语句; end 6. 循环的跳转 for num = 1: 10   语句1;   if 条件     continue;   end   语句2; end 三、switch语句 switch语句可以使用得很灵活: switch 变量名 case 1   语句1; case {2; 3}   语句2; case ‘a’   语句3; case {’b’; ‘c’}   语句4; otherwise   语句5; end 6. 关于Object句柄的获取 通过 findobj 可以根据Object的属性来获取其句柄来进行其它操作,但对于手工加入的Object,如:用鼠标绘制的直线,或加入的文字框(用text或gtext加入的可以)好象不行,请问如何获取这些对象的句柄。 有几个办法。关键在于使用findall,而不是findobj。  如果你只有一条线。也就是在matlab里用figure命令,然后用figure窗口工具栏的Insert line画一条线,那么可以这样获得所画线条的句柄: 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。通常用手工添加的线条的数据点只有两个,即起始点和终止点,而用plot等所画的线条其数据点数目比较多,所以可以通过判断数据点个数来找出手工钱家对象。 numOfPts = length(get(hLines(i), 'Xdata')); % 用循环遍历所有句柄 3. 既然是手工添加,当然应该明白所添加线条的位置,所以可以通过判断该线条的起始点和终止点的坐标值来判断,这种方法适合于手工添加两条以上的线条。 4。最佳方法就是:既然是手工添加,那么在添加线条以后,顺手用鼠标双击该线条,在出来的Property窗口,Info标签下面,给这个线条一个Tag,那么在程序里就可以通过这个tag来唯一的确定该对象: hMyLine = findall(gcf, 'Tag', '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') 用copyobj将axes拷到fig上 这个可以在你的GUI有多个AXES时使用 如果对GUI基本内容有初步了解,请尝试: axes(haxesi)%haxesi为想设为当前轴的轴句柄。 或者注意set中的currentaxes属性。即:找到该轴句柄并设为当前set(gcf,'currentaxes','haxesi') 如果实在GUI里面做多个轴,可以在handles句柄当中找到这个轴 如果有多个轴,首先将你的轴的Tag修改为您认为方面的名称,比如说两个轴,分别叫myAs1和myAx2。这样的轴或者控件的句柄都可以在默认的handles结构当中直接找到。 如果你想在 myAx1上面画图, 可以用axes(handles.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的采样时间这个属性的名称,就可以用这个命令来得到: 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] 看到没,SampleTime就是它的采样时间。 好了,这时候你就可以通过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=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的position强制给 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的朋友有兴趣可以一试,看来7.3还是满有点儿意思的... function tryone clc h = 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','改变图形色系到hot',...     'ClickedCallback',['peaks;','colormap(hot)']); 11. 如何将计算结果保存到.txt文件中 1      fop=fopen('d:test.txt','w+');    %算一个a    a=1;    fprintf(fop,'%f\n',a);    %再算一个a    a=2;    fprintf(fop,'%f\n',a);    fclose(fop) 2.   把所有的a存起来   %A=[a1 a2 ...]   a=1:10;   save 'd:test1.txt' a -ASCII 12. 使用摄像头连续采集、保存图像源程序 写了一个在matlab2006上用摄像头连续采集、保存图像源程序。运行imaq_test.m文件后,弹出保 存对话框,指定一个存盘目录,选定保存格式(如.jpg),输入主文件名(如aqim),点击'开始采集 按钮,将以设定的频率采集图像,并以aqim1.jpg,aqim2.jpg...保存在选定的文件夹中。 不知道有没有更好的实现方式,希望大家能给出新的简洁思路,谢谢。 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %保存为 imaq_test.m hfig=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.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 (*.*)'}, ...         '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('winvideo'); 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.m hfig=figure; hpush1=uicontrol(gcf,'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.m himage=findobj(gcf,'type','image'); riceimg=get(himage,'CData'); [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 (*.*)'}, ...         'Save as'); fullpath=[pathname,filename]; imwrite(riceimg,fullpath,'quality',100); 运行savetest , 点击界面上的saveas ,选则路径、确定文件名、类型,保存 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 Chinese characters.      operation:    A row vector of string ,the operation made to the window                    who's title is window_title.      The second argument operation can has such values:         1.'topmost'    Make the window always on top of other windows         2.'notopmost'  Cancel the property of aways on top of the window     .      3.'maximize'   Maximize 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编程是否可以实现选项卡的功能? 标签视图代码,基于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'}; tabDims{1}=[80 50 50 50]';tabDims{2}=16; callback='tabchange'; sheetDims=[800  400]; offsets=[3 5 5 3]'; d
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传
相似文档                                   自信AI助手自信AI助手

当前位置:首页 > 通信科技 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服