资源描述
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
展开阅读全文