matlab GUI界面编程
创建Matlab GUI界面通常有两种方式:
1,使用 .m 文件直接动态添加控件
2. 使用 GUIDE 快速的生成GUI界面
显然第二种可视化编辑方法算更适合写大型程序。
一:创建GUI
1.在 .m文件中动态添加
例如
h_main=figure(‘name’,‘a demo of gui design’,‘menubar’,‘none’,…
'numbertitle','off','position',[100 100 300 100]);
h_edit=uicontrol('style','edit','backgroundcolor',[1 1 1],'position',[20 20 50 20],...
'tag','myedit','string','1','horizontalalignment','left');
h_but1=uicontrol('style','pushbutton','position',[20 50 50 20],'string','INC',...
'callback',['v=eval(get(h_edit,''string''));',...
'set(h_edit,''string'',int2str(v+1));']);
h_but2=uicontrol('style','pushbutton','position',[80 50 50 20],'string','DEC',...
'callback',['v=eval(get(h_edit,''string''));','set(h_edit,''string'',int2str(v-1));']);
![](http://lh6.ggpht.com/_TTElQjurMCc/STErpKgwfSI/AAAAAAAAJtI/K_rthfVVA9A/s800/moz-screenshot-5.jpg)
2.使用GUIDE帮助创建GUI
在Command 里面输入 GUIDE 或者从菜单里面,或者从快捷按钮均可 进入 GUIDE
新建并且保存后,会生成相应的fig文件和m文件,在Layout编辑视图,可以使用如下工具:
Layout Editor:布局编辑器;
Alignment Tool:对齐工具;
Property Inspector:对象属性观察器;
Object Browser:对象浏览器;
Menu Editor:菜单编辑器。
二:使用控件
新建一个布局(窗口),可以在新窗口中添加如下控件
1.静态文本(Static Text) 2.编辑框(Edit Text)控件
3.列表框(Listbox)控件 4.滚动条(Slider)控件
5.按钮(Push Button)控件 6.开关按钮(Toggle Button)控件
7.单选按钮(Radio Button)控件 8.按钮组(Button Group)控件
9.检查框(Check Box)控件 10.列表框(Listbox)控件
11.弹出式菜单(Popup Menu)控件 12.坐标轴(Axes)控件
13.面板(Panel)控件
每一个控件都有自己的属性常规属性有:
一、控件风格和外观
(1)BackgroundColor:设置控件背景颜色,使用[R G B]或颜色定义。
(2)CData:在控件上显示的真彩色图像,使用矩阵表示。
(3)ForegroundColor:文本颜色。
(4)String属性:控件上的文本,以及列表框和弹出菜单的选项。
(5)Visible:控件是否可见。
二、对象的常规信息
(1)Enable属性: 表示此控件的使能状态,设置为on”,表示可选,为“off”时则表示不可选。
(2)Style:控件对象类型。
(3)Tag:控件表示(用户定义)。
(4)TooltipString属性:提示信息显示。当鼠标指针位于此控件上时,显示提示信息。
(5)UserData:用户指定数据。
(6)Position:控件对象的尺寸和位置。
(7)Units:设置控件的位置及大小的单位
(8)有关字体的属性,如 FontAngle, FontName等。
三、控件回调函数的执行
(1)BusyAction:处理回调函数的中断。有两种选项:即Cancel:取消中断事件,queue:排队(默认设置)。
(2)ButtonDownFcn属性:按钮按下时的处理函数。
(3)CallBack属性:是连接程序界面整个程序系统的实质性功能的纽带。该属性值应该为一个可以直接求值的字符串,在该对象被选中和改变时,系统将自动地对字符串进行求值。
(4)CreateFcn:在对象产生过程中执行的回调函数。
(5)DeleteFcn:删除对象过程中执行的回调函数。
(6)Interruptible属性:指定当前的回调函数在执行时是否允许中断,去执行其他的函数。
四、控件当前状态信息
(1)ListboxTop:在列表框中显示的最顶层的字符串的索引。
(2)Max:最大值。
(3)Min:最小值。
(4)Value:控件的当前值。
你可以使用属性编辑器来设置属性
三:写回调函数 CallBack
每个控件都有几种回调函数,右键选中的控件一般会有如下菜单:
然后就可以跳转到相应的 Editor中编辑代码,GUIDE会自动生成 相应的函数体,函数名,名称一般是 控件 Tag+ Call类型名 参数有三个 ( hObject, eventdata, handles)
其中 hObject 为发生事件的源控件,eventdata为事件数据结构,handles为传入的对象句柄
CreateFcn 是在控件对象创建的时候发生(一般为初始化样式,颜色,初始值等)
DeleteFcn 实在空间对象被清除的时候发生
ButtonDownFcn和KeyPressFcn分别为鼠标点击和按键事件Callback
CallBack为一般回调函数,因不同的控件而已异。例如按钮被按下时发生,下拉框改变值时发生,sliderbar 拖动时发生等等。
四:句柄图形之间的层次关系
可以创建 图形句柄的常见函数
1.figure函数:创建一个新的图形对象。
2.newplot函数:做好开始画新图形对象的准备。
3.axes函数:创建坐标轴图形对象。
4.line函数:画线。
5.patch函数:填充多边形。
6.surface函数:绘制三维曲面。
7.image函数:显示图片对象。
8.uicontrol函数:生成用户控制图形对象。
9.uimenu函数:生成图形窗口的菜单中层次菜单与下一级子菜单。
几个实用的小函数:
uigetfile 选择文件对话框
uiputfile 保存文件对话框
uisetcolor 设置颜色对话框
fontsetcolor 设置字体对话框
msgbox 消息框
warndlg 警告框
helpdlg 消息框
不过如果要让父窗口不可用,你需要使用uiwait来定焦于用户对话框。
例如:
h=helpdlg('Please press me!','Attention');
uiwait(h);
四:获取与设置对象属性
常用函数:
gcf函数:获得当前图形窗口的句柄
gca函数:获得当前坐标轴的句柄
gco函数:获得当前对象的句柄
gcbo函数:获得当前正在执行调用的对象的句柄
gcbf函数:获取包括正在执行调用的对象的图形句柄
delete函数:删除句柄所对应的图形对象
findobj函数:查找具有某种属性的图形对象
设置方法:
(1)get函数返回某些对象属性的当前值。例如:
p=get(obj,'Position');
(2)函数set改变句柄图形对象属性,例如:
set(obj,'Position',vect);
五:函数调用
在一个m文件中,可以定义多个函数,但是文件名一定要与第一个函数(主函数)一致,
该文件中其他函数则为本文件的私有函数,外部不可访问(可以通过参数调用的方法访问,下面会描述)。
例如在一个程序中,创建一个fig后,会生成这样一个m文件:
function varargout =febirdfun(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @febirdfun_OpeningFcn, ...
'gui_OutputFcn', @febirdfun_OutputFcn, ...
'gui_LayoutFcn', [], ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
解析 一下这个主函数:首先 gui_State是一个结构,指定了figure打开和输出函数,
开始 gui_CallBack为空,如果输入参数个数不为0,接下来将输入第一个参数传递给gui_State.callback。
接下来用交给 gui_mainfcn函数处理,gui_mainfcn 根据gui_State和传入参数
来确定是执子函数,还是打开 fig 文件和运行 OpeningFcn和OutputFcn。
如过 gui_Callback为空,那么就运行打开主窗口fig文件,否则,调用子函数
这个函数的作用有:
1.当输入不带参数的时候,能够打开fig文件,并且初始化控件
2.当指定需要调用的函数名时,可以作为其他控件callback使用 (实则调用同文件中的子函数)
例如,在某一个控件的 callback 里面这样写:(febrdfun为主函数)
febirdfun("@push_button_Callback",gcbf,[])
这样的调用就可以调用文件里面的子函数。
当然也可以使用其他文件里面的函数作为callback,不过那样的话,数据传递会麻烦一些。
下面看figure Openning Function
%================================
function Main_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
% 通常在这里面定义自己的数据结构例如
s=struct("P1",v1...
"P2",v2);
handles.MyStruct=s;
% 更新handles数据结构 非常重要!!
guidata(hObject, handles);
%================================
function varargout = Main_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
这个函数是输出返回值的定义
注意: matlab 中,function 对应的 end 可以没有,但是随着版本的更新,end将会被要求。
六:数据传递
在matlab GUI程序中进行值传递我经常使用的两种方法:
1.利用主函数 的 handles 数据结构传值
例如在某一个图像窗口句柄 中有一个对象 handles(可以定义自己的数据结构)
那么在一个子Callback函数中,可以通过handles传递数据:
function sliderbar1_Callback(hObject,eventdata,handles)
%% eg1
v1=get(hObject,'value');
obj=handles.Text1 %直接定位 Tag 为 Text1的控件
set(obj,'value',v1);
%% eg2
handles.MyStruct.P1=v1; % 更改handles中的数据
guidata(hObject,handles); %更新 handles !!重要
end
2.利用控件的 UserData 来传值
每一个控件一般都有一个属于自己的自定义域,userData,你可以定义这样一个域用来保存自己的数据,例如在定义 timer 的 TimerFcn中
t1=timer('TimerFcn',{@Timer1Fcn},'ErrorFcn',@Timer1ErrorFcn},'Period',1.0,'ExecutionMode','fixedrate');
t1.Userfata=handles.MyStruct;
这里 Timer1Fcn的调用看似没有传入任何参数,实际上此函数的定义一定要有至少两个参数
function Timer1Fcn(obj,eventata)
obj.UserData=XXXXX;%可以这样共享数据
end
当然Timer定义的时候允许这样传递一个参数,当然这样也可以进行传值.
t1=timer('TimerFcn',{@Timer1Fcn,handles},'ErrorFcn',{@Timer1ErroFcnr,handles},'Period',1.0,'ExecutionMode','fixedrate');
===============================================
MATLAB-图像处理GUI-1布局
总体布局
添加控件,然后编写回调函数。控件有个叫Tag的属性,是编程用到的。.m文件里的Tag_Callback就是回调函数。触发控件后就会执行回调函数。
最上面是菜单栏和工具栏。下面一横是按钮群,选择一类处理方法。左边是具体功能和每个功能的参数。右边放一些通用操作。下面是信息框。
1. 界面自适应大小
tool->gui options:Resize behavior里选Proportional
![](https://upload-images.jianshu.io/upload_images/11370280-33f4976a9b1ab65b.png?imageMogr2/auto-orient/strip|imageView2/2/w/514/format/webp)
2. 菜单栏
点击菜单栏的Tool->Menu Editor(工具栏也有),弹出窗口。添加Menu和Menu Item。修改对应的参数。
![](https://upload-images.jianshu.io/upload_images/11370280-8cde5630cc942f13.png?imageMogr2/auto-orient/strip|imageView2/2/w/703/format/webp)
3. 工具栏
点击菜单栏的Tool->Toolbar Editor(工具栏也有),弹出窗口。从下面拖按键到上面那一栏,然后编辑属性。
![](https://upload-images.jianshu.io/upload_images/11370280-4f25eef6201f7707.png?imageMogr2/auto-orient/strip|imageView2/2/w/703/format/webp)
4. 其他的就是从左边拖过来然后编辑参数了
matlab GUI 新手入门——最基本的几个概念
1、从最简单的开始
编程的基本思想是:我执行一个操作,程序做出一个反应。“一个操作”包括点击鼠标、拖动滑块、填写数据、选择选项等;“做出一个反应”包括计算、储存在哪里、贴个图出来、显示在哪里。
简言之:当点击按钮A时, 然后执行任务C,则进入按钮A的回调函数callback里,写下任务C的代码。
几个基本概念:
CallBack: 最常用的。点击按钮时,按钮下的Callback就会执行;拖动滑块时,滑块名下的callback就会执行;总之,正常用途全放在callback下。
ButtonDownFcn:单击,这个函数名下的代码就会执行。(ps:按钮的callback也是点击,覆盖掉buttondownfcn。)
CreateFcn:顾名思义,在生成这个控件,显示之前,执行这个函数名下的代码。
DeleteFcn: 顾名思义,在控件要销毁,但是被毁灭之前执行这个函数名下的代码。貌似“真的要退出吗”这一类。
KeyPressFcn:当前控件获得焦点且有按键按下时执行。
SelectionChangeFcn:在群按钮组件中改变选择时,所执行的函数。
2、常用控件代码框架参考
Toggle Button 的callback一般写法
functon togglebutton1_callback(hObject,eventdata,handles)
%这一句不用管。自动加的。
button_state = get(hObject,'Value')
%控件甲的callback下面hObject就是控件甲,同理控件乙callback下的hObject......
if button_state==get(hObject,'Max')
%则……
else if button_state==get(hObject,'Min')
%则……
end
PS:button_state是变量名,存放按钮的选择状态。如果button甲放在一个buttonGroup里,则button甲callback下的代码就要挪到buttonGroup下面去。因为buttonGroup的回调函数会覆盖掉它成员的回调函数。
Radio Buttons
右键Radio按钮,进入编辑callback
function ………………略
if(get(hObject,'Value')==get(hObject,'Max'))
%被选中了,你想怎么样
else
%不被选中,你想怎么样
end
Check Boxes
if(get(hObject,'Value')==get(hObject,'Max'))
%被选中了,你想怎么样
else
%不被选中,你想怎么样
end
Edit Text
function edit1_Callback(hObject,eventdata,handles)
user_string = get(hObject,'String'); %就得到了所输入的字符
%matlab把所有输入当作字符,如果期望输入数据,则进行数据类型转换:
user_entry= str2double(get(hObject,'String'));
if isnan(user_entry) %nan就是not a number的简写。
errodlg('You must entry a number value','Bad Input','modal') %跳出一个对话框。
end
PS: 'Bad Input'是指窗口样式,如黄色感叹号或者红叉的对话框;modal是指窗口类型,如警告对话框。
Sliders
function slider1_callback(hObject,eventdata,handles)
slide_value=get(hObject,'Value');%获取滑块当前值
%别的代码
PS:它的Max Min 属性设置了滑竿的最大最小范围值。
List Boxes
function ........
index = get(handles.listbox1,'Value'); %listbox1控件的tag名
file_list =get(handles.listbox1,'String'); %得到了listBoxes的列表
file_name = file_list{index};%得到了所选择的项目名
%别的代码
PS:此callback在鼠标在这个控件上松开或者特定的键盘按键松开(看怎么设置属性)时执行。默认键盘上下键可以改变它的值同时执行一次callback。而enter和space不改变它的值,只是执行callback。Max-Min 差值是0的话,表示只可以单选;1的话,表示可以多选。这个可以在他的属性栏里设置。
Pop_up Menus
function .......
val=get(hObject,'Value')
Switch val
case 1
%
case 2
%
defualt
......
end
Button Groups
function .......
switch get(hObject,'Tag');%注意这里的hObject和别的不同,不是指Button Group,而是指在组里面被选中的那个控件
case 'radio button1' %按钮1的tag
%。。。。。
case '按钮2的tag'
%。。。。。
end
Axes
axes(handles.youraxesname);%选择一个axes
plot(x,y); %这时所画的图就到它上面了
set(handles.youraxesname,'XMimrFrick','on'); %顺便设置一下它的属性
grid on; %加上网格
3、怎么获得和设置控件的属性
通俗的说,就是怎么获取编辑框里的字符、滑块现在的位置、pop up里被选中的选项,如何控制static text显示我要求的信息等。
设置:set(handles.控件的tag,'要设置的属性名','要设置的属性值')。比如:set(handles.edit1,'string','hello world');
获取:get(handles.控件的tag,'要获取的属性名')
help里可以看到所有可能有用的属性:MATLAB->Creating Graphical User Interfaces->Laying Out GUIs and Setting Properties->What Properties Do I Need to Set?
4、数据怎么在不同的控件之间传递
先看在一个GUI界面内部的传递数据。每一个控件的回调函数头:function myc_Callback(hObject, eventdata, handles)
第一个参数是hObject,是跟这个callback所关联的控件的handles,在它自己的callback下,可以用代号-> hObject 来调用它。即控件自己的回调函数调用自己的属性,只用hObject.属性名就可以了(中间一点)。
第二个参数是MATLAB的保留参数。
第三个handles是这个GUI界面的代号,可以通过它获取这个界面的所有信息。所以在控件A自己的回调函数中,要获取或者设置别的控件的属性,就用 handles.别的控件Tag.属性
handles hObject 都是结构体。handles格式是一个存放数据的缸。控件的handles是小缸,它的名字叫做hObject;GUI界面的handle是一个大缸,并且这个缸名字也叫做handles;大缸里存放了所有的小缸和所有用户数据,你只需handles.控件A的tag,就可以存取控件A的信息。
把自己计算出或者别的什么数据放到这个缸里,可以在任何地方:
handles.变量名 = 某些值 (其实也就是给结构体添加成员变量)
b=handles.变量名 (结构名加点号来引用成员变量)
就可以得到这个变量值,同样也可以修改它。
别忘了使用guidata(hObject, handles);在函数末尾来保存你对handles和hObject的操作。(不然你自定义的变量就没了)
5、在不同GUI之间传递数据
传入:
先看打开一个GUI界面时,传给他的参数有哪些。
function mygui_OpeningFcn(hObject, eventdata, handles, varargin)
所有的启动参数都是通过varargin传到它的OpeningFcn里面的。启动参数包括:
figure,也就是窗口参数,如position之类。例如:打开这个GUI时,使用命令mygui('Position',[434 234 234 34])表示打开窗口在这个位置;还有哪些可控属性可以查help。
自定义参数,如果传入的参数不是figure的属性(matlab查找不到你输入的属性名),则输入的参数作为一个向量存放在varargin里面。比如mygui('路人甲','80‘),那varargin{1}存放了'路人甲',varargin{2}=’80‘
传出:
看每一个GUI的最外层的那句 function varargout = mygui(varargin)。把GUI本身看做一个函数,b=mygui(一些传入的参数) 就执行GUI并返回结果,b就得到了传出来的结果。
在GUI任意地方,将要输出的数据存在handles.output里面。
handles.output=数据1;
handles.secend_output=数据2;
然后在GUI的outputFcn里面加上
varaginout{1}=handles.output;
varaginout{2}=handles.secend_output;
Matlab-GUI编程:简单计算器的实现
前言:任何编程语言到了GUI这一块都逃不了要模仿做一个计算器来证明已经入门了。
界面准备
这就跟java很不一样了,java的一切空间都是需要自己创建的对象,而matlab提供一个类似画图界面的操作窗口可供用户可视化操作,当然他背后的.m文件也会自动相应地生成功能函数。
![](https://upload-images.jianshu.io/upload_images/2573296-0bde8ebed88c8387.PNG?imageMogr2/auto-orient/strip|imageView2/2/w/615/format/webp)
计算式框和结果框都是静态文本,下面按钮使用pushbutton
当然,控件的样式操作也很方便,直接调出控件的属性查看器,直接修改样式属性。(有一种ppt的感觉有没有。。。)
![](https://upload-images.jianshu.io/upload_images/2573296-ae4d01f5c5d899be.PNG?imageMogr2/auto-orient/strip|imageView2/2/w/509/format/webp)
属性查看器界面
相当于这个控件对象的一些属性可以在这个界面人工修改。例如string属性是控件静态显示文本,java里面需要调用setText(j)方法来设置。比较重要的是tag属性,相当于对象的名字,最开始都是系统自动起的名字。对象名当然很重要,不知道对象名怎么调用属性?怎么调用方法?
功能代码实现
计算器啥功能?基本的运算,得出一个多项式结果后还能接着这个结果运算是吧?当然最开始还得实现出发button传值是不,我们一步一步来实现:
首先一个比较重要的功能就是,控件相应功能的函数位置,因为创建控件后,matlab会自动地在.m文件中写入对象的初始化函数、回调函数(相当于java中的事件监听函数)。
右键控件->查看回调->callback,然后matlab脚本编辑页面会自动跳转至相应的代码行,这个函数下的代码就是当你触发这个控件时所执行的代码。
控件传值
首先要做的是将数字、运算符按钮上的值传到计算框内:
```matlab
function pushbutton8_Callback(hObject, eventdata, handles)
s1=get(handles.text2,'string')
s2=get(hObject,'string')
set(handles.text2,'string','')
set(handles.text2,'string',strcat(s1,s2))
```
这个比较简单,就是set(对象名,属性名,属性值) get(对象名,属性名)的使用,这两个函数在GUI编程中是最常用的。当然这个调用对象属性的风格颇像C语言...
算术表达式的运算
前面所有的数字、运算符的传递到静态文本框内的都是string格式,那么怎么计算这个字符串格式的算术式从而显示结果到结果框中呢?
嗯,巧了,正在修的数据结构(使用C语言)告诉我,利用堆栈数据结构将字符串转化成后缀表达式,再出栈运算.....
但是matlab作为一个重达几个G的软件不会连这个都要我们自己编算法吧?
好的,肯定不会 ,下面的eval函数就是这功能:
```matlab
str=get(handles.text2,'string')
answer=eval(str)
set(handles.text4,'string',num2str(answer))
```
来,我们先看下目前的效果:
![](https://upload-images.jianshu.io/upload_images/2573296-19b51c4fa678e092.gif?imageMogr2/auto-orient/strip|imageView2/2/w/646/format/webp)
连续运算
接下来解决的就是连续运算了,就是接着上步结果接着算。那么要干两件事:上步结果显示在输入框内、符号键第二次点击执行不同的代码。
比较难做到的就是第二点。比如我们第一次点击“+”时,是正常的运算。运算完结果后,第二次再点击+时应该接着上步运算,此时执行的代码就不一样了。
我解决的办法是设置全局变量, 每个运算符回调函数下设置 global i=0,执行完第一次之后把i置1;当然AE按钮执行后要重新置成0;
这样运算符的代码修改为这样:
```matlab
global i
if i==0
s1=get(handles.text2,'string')
s2=get(hObject,'string')
set(handles.text2,'string',strcat(s1,s2))
else
set(handles.text2,'string','')
s=get(handles.text4,'string')
ss=get(hObject,'string')
set(handles.text2,'string',strcat(s,ss))
end
i=i+1
```
现在的效果:
![](https://upload-images.jianshu.io/upload_images/2573296-f92bc7dde57850f5.gif?imageMogr2/auto-orient/strip|imageView2/2/w/646/format/webp)
实现连续计算
这样就差不多了,然而有个bug,就是这样一来输入框就只能进行二项式的运算了,多项式如果第二次输入同一个运算符就gg了。这就需要再计算按钮上再设置计数器,然后在在运算按钮上加条件判断....
好吧,接下来的就不写了,因为GUI只要掌握图形界面背后代码是怎样实现的就ok了。