书名:MATLAB GUI纯代码编写从入门到实战
ISBN:978-7-115-62229-7
本书由人民邮电出版社发行数字版。版权所有,侵权必究。
您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。
我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。
如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。
编 著 苑伟民
责任编辑 李永涛
人民邮电出版社出版发行 北京市丰台区成寿寺路11号
邮编 100164 电子邮件 315@ptpress.com.cn
网址 http://www.ptpress.com.cn
读者服务热线:(010)81055410
反盗版热线:(010)81055315
本书介绍如何使用代码(.m与.mlx文件)开发图形用户界面(GUI),辅以大量的编程示例详细讲解基于figure函数的uicontrol、容器、坐标区、常用控件、图窗工具、检测控件、对话框和通知,基于uifigure函数的对话框和通知,以及布局函数、控制流函数、App数据和预设函数等内容。
与采用GUIDE、App Designer的方式相比,用代码开发的GUI能兼容几乎所有的MATLAB版本,灵活性和适用性较强,且便于重构。
本书适合有一定代码编写基础且想快速入门MATLAB GUI的人员学习,可以作为高校学生的教材,也可以作为从事管理、技术、研发等工作的人员的学习参考书。
古人云“工欲善其事,必先利其器”。科学计算在科技工作者的工作中占有相当大的比例。MATLAB作为一个科学计算“神器”则是我们必不可少的工作“利器”。无论是在辅助计算、科学研究还是日常工作中,我们往往会根据实际需求利用MATLAB开发一些或大或小的程序,以便提高效率。但是,随手编写的程序往往没有GUI。有没有办法让我们的程序“脱胎换骨”,走出“深闺”,服务于大众呢?答案是“有”——给MATLAB程序编写GUI。有了GUI,小程序就能“闯荡江湖,扬名立万”——服务于大众。同时,也能让程序开发者的才华有用武之地。
MATLAB GUI的编写方式有多种,各种介绍资料也很多,不过多集中于应用各种辅助工具进行编写,而专注于介绍纯代码编写的不多。纯代码编写(指在编程中直接使用文本编辑器或集成开发环境,而不依赖可视化工具)是一种返璞归真的开发方式,具有许多优点。
一是灵活性和控制性较强。使用纯代码编写,您可以完全掌控应用程序的每个方面。您可以编写自定义算法、逻辑和界面,以满足特定需求,而不受可视化工具的限制。
二是可重复性较好。代码是可重复使用的。一旦您编写了代码,可以轻松地将其用于其他项目或场景,从而节省时间和减少工作量。
三是版本控制容易。使用版本控制系统(如Git)管理代码变更非常容易。这有助于跟踪项目的发展历史、协作开发和回滚到以前的版本。
四是便于进行性能优化。对于需要高性能的应用程序,通过编写代码可以更好地优化和控制资源使用情况,以提高性能和效率。
尽管纯代码编写具有这些优点,但也需要更多的编程技能和经验。因此,我推荐这本《MATLAB GUI纯代码编写从入门到实战》。该书是一本非常实用和深入的指南,适合那些希望在MATLAB中创建强大GUI的人。该书以清晰的语言、详细的示例和逐步指导的方式,带领读者探索MATLAB中GUI开发的方方面面。
作者通过深入剖析MATLAB的GUI工具箱,以及从基础到高级的编程技巧,使读者能够轻松地构建自己的GUI。不仅如此,书中还包括实际应用示例,让读者能够将所学的知识直接应用到自己的项目中,提高工作效率并增加MATLAB应用的交互性。
最后,衷心祝愿您通过这本书给自己的程序配上方便、实用的GUI,展现您的才华,服务于大众,服务于社会。
我由衷地向您推荐《MATLAB GUI纯代码编写从入门到实战》!
中国石油大学(北京)李晓平
2025年1月
MATLAB GUI是一种图形窗口,可以向其中添加用户能操作的组件,可根据需要选择、调整和放置组件。使用回调函数,可以使组件在用户单击或通过按键操作时执行相应的操作。
创建MATLAB GUI主要有以下3种方法。
(1)使用GUIDE(GUI开发环境)。
(2)以交互方式,使用App设计工具(App Designer)。
(3)以编程方式,使用MATLAB函数。
这些方法中的每一种都提供不同的工作流程和一组略有不同的功能。
(1)使用GUIDE创建GUI。
该方法从拖曳图形布局编辑器中的组件进行布置开始。使用GUIDE创建一个关联的代码文件,其中包含GUI及其组件的回调函数。GUIDE在保存图形(.fig文件)的同时会自动保存代码文件,打开其中一个时也会自动打开另一个以运行GUI。
该方法已经被MATLAB建议停用,但目前仍能使用。
(2)使用App设计工具创建GUI。
App设计工具是MATLAB R2016a中引入的丰富的交互环境,是在MATLAB中构建应用程序的推荐环境。它包括一个完全集成的MATLAB编辑器。布局视图和代码视图紧密相连,因此在一个视图中所做的更改会立即影响另一个视图。与GUIDE相比,App设计工具提供了更多的交互式组件,包括日期选择器、树和图像;还有一些组件,如网格布局管理器,可让应用程序实现自动检测并适应屏幕尺寸的变化。
App设计工具是MATLAB推出的替代GUIDE的一款产品。如果想学习App设计工具,可以参考《MATLAB App Designer从入门到实践》一书。
(3)使用MATLAB函数创建GUI。
可以完全使用MATLAB函数对应用程序的布局和行为进行编码。利用这种方法,可以使用uifigure或figure函数创建一个图形作为UI(用户界面)的容器,然后以编程方式向其中添加组件。创建代码文件定义所有组件的属性和行为;当用户执行文件时,它会创建一个图窗,用组件填充它,并处理用户交互命令。与使用GUIDE和App设计工具创建GUI相比,以纯代码方式创建的GUI对各版本的MATLAB适用性比较好,这是它的一个优势。此外,MATLAB软件还提供简化标准对话框(例如发出警告或打开和保存文件的对话框)创建的功能。
本书主要介绍以基于uifigure函数和figure函数的编程方式创建GUI、进行交互及简化标准对话框的创建等内容。
由于笔者水平有限,书中难免存在一些不足之处,欢迎广大读者对书中内容提出宝贵意见和建议,以便笔者进行修改,笔者联系邮箱:yuanvmin@hotmail.com。
苑伟民
2025年1月
在MATLAB中使用纯代码编写GUI的方法适用性非常好,它基于.m或者.mlx脚本文件,几乎用任何版本的MATLAB纯代码生成的GUI都不会出现版本不兼容的问题,这种编写方法结合“使用ASCII表示中文字符”的方法,是非常可靠的GUI编写方法。该方法并没有像GUIDE和App Designer那样流行,因为它需要编程者熟知每种控件的编写代码和属性,在界面排版方面没有在画布上拖放控件直观、快捷,但是该方法容易入门,使用相对简单。本书将每个控件用到的属性一一列出并对其做解释,方便读者查询和使用。
下面3个示例演示了采用代码编写GUI的不同属性设置。
下面一段代码展示了按钮随着窗口大小的改变而改变,起到这个作用的关键字为'Units', 'normalized',这是一对名值(Name,Value)参数对,逗号前面为属性名,后面是该属性的值。Units为单位(大小的量度),normalized的意思为归一化。
f1=figure('Units', 'centimeters', ... 'position',[2 6 6 6],'menubar','none', ... 'numbertitle','off','resize','on'); str = '<html>会当凌绝顶,<br>一览众山小。</html>'; h1=uicontrol('Style', 'pushbutton', ... 'Units', 'normalized','FontSize', 12, ... 'position', [0.2 0.4 0.6 0.3], 'string', str);
运行结果如图1-1所示。
图1-1 运行结果(1)
Units属性指定为表1-1中的一个值。
表1-1 Units属性的值及说明
值 |
说明 |
---|---|
'normalized'(默认值) |
针对包含注释的图窗、uipanel或uitab进行归一化。容器的左下角映射到(0,0),右上角映射到(1,1) |
'inches' |
英寸,1英寸≈2.54厘米 |
'centimeters' |
厘米 |
'characters' |
基于系统默认字体的字符大小。 字符宽度=字母x的宽度 字符高度=两个文本行的基线的距离 |
'points' |
磅,1磅=1/72英寸 |
'pixels' |
像素 |
Position属性的值[left bottom width height]代表[与父容器左边的距离 与父容器底边的距离 该控件的长度 该控件的高度]。
无论采用什么单位,生成的对象的位置都是以父容器左下角为基准进行测量的。
Units属性会影响Position属性。如果编程者更改Units属性的值,则比较好的做法是在完成该段代码运行后将其恢复为默认值,以便不影响其他假定Units属性为默认值的函数。
如果编程者在创建对象时以名值参数对的形式指定Position属性和Units属性,则指定顺序很重要。如果想用特定单位定义位置,则必须在设置Position属性之前设置Units属性。
下面一段代码展示了单位为厘米,并且增加了前景色为蓝色、字体为斜体的示例。如果不指定父容器,则MATLAB给出默认的父容器,该父容器的大小可以在命令行窗口输入f=get (figure); f.Position语句来获取。运行结果如图1-2所示。
str = '<html>欲穷千里目,<br>更上一层楼。</html>'; h2=uicontrol('Style', 'pushbutton', 'FontSize', 12, ... 'Units', 'centimeters','position', [3,3,3,2], ... 'string', str,'ForegroundColor','blue', ... 'FontAngle','Italic');
图1-2 运行结果(2)
下面一段代码展示了颜色设置的另一种方式——用矩阵代表颜色。运行结果如图1-3所示。
str = '<html>欲穷千里目,<br>更上一层楼</html>'; h3=uicontrol('Style', 'pushbutton', ... 'FontSize', 12,'String', str); h3.Position=[50 50 150 80]; set(h3,'ForegroundColor',[1,0,1]);
图1-3 运行结果(3)
从上面的示例可以看出,代码不仅可以写为一句长代码,也可以分段书写。
上面的示例涉及图形对象、图形对象句柄、图形对象属性、图形句柄操作等内容。
图形对象很容易理解,就是显示出来的图形及控件,可以通过设置底层对象的属性自定义图形。每个对象在图形中都具有特定的角色。例如,图形可能包含线条、文本和坐标区,它们都显示在图窗中。
每个对象都有一个名为句柄的唯一标识符。在创建对象后,MATLAB会返回该句柄值。编程者可以通过操作该句柄(如前面例子中的h1、h2、h3),查看、修改、设置对象属性来操作现有图形对象的特征。编程者还可以在创建图形对象时指定属性值。
当创建图形(如通过调用plot函数创建图形)时,MATLAB会自动执行一系列步骤生成图形。这些步骤包括创建对象和将这些对象的属性值设置为适合特定图形的值。
图形对象的层次结构组织如图1-4所示。
图1-4 图形对象的层次结构
图形对象的层次结构本身反映出对象之间的包含关系。
例如,用户使用plot函数创建线图。坐标区对象定义了表示数据的线条的参考框架,图窗是显示图形的窗口。图窗包含坐标区,坐标区包含线条、文本、图例,以及其他用于表示图形的对象。用户可以通过设置它们的属性来自定义图形对象。
注意 |
坐标区是表示x、y和z坐标区标度、刻度线、刻度标签、坐标区标签等对象的单个对象。 |
图1-5所示是一个简单的图形示例。
图1-5 图形示例
该图形形成了对象层次结构,如图1-6所示。
图1-6 图形示例的对象层次结构
对象间的关系保存在Parent属性和Children属性中。例如,坐标区的父级是一个图窗。坐标区的Parent属性包含该坐标区所在图窗的句柄。同样,图窗的Children属性包含其所含的所有坐标区,还包含其所含的其他所有对象,如图例和用户界面对象。
用户可以使用父子关系找到其他对象句柄。例如,如果绘制一个图形,当前坐标区的Children属性包含所有线条的句柄,代码如下,运行结果如图1-7所示。
plot(rand(5)) ax = gca; ax.Children ans = 5x1 Line array: Line Line Line Line Line
图1-7 运行结果(1)
提示 |
ax=gca表示返回当前图窗中的当前坐标区(或独立可视化)。使用ax获取和设置当前坐标区的属性。 |
用户还可以指定对象的父级。例如,创建一个组对象,让该组对象成为坐标区中线条的父级,即让新生成的图形在上一个图形的基础上显示,代码如下,运行结果如图1-8所示。
hg = hggroup; plot(rand(5),'Parent',hg)
图1-8 运行结果(2)
综上所述,使用代码编写GUI,就是通过设置图形对象属性、定义默认值等来实现GUI的创建和修改。
用户可以通过设置特定图形对象的属性来控制其行为和外观。要设置属性,可通过创建该对象的函数将其以输出参数的形式返回。例如,使用plot函数返回图形线条对象,然后,使用圆点表示法查看和设置属性。
p = plot(1:10,1:10); p.LineWidth = 3;
用户也可以在创建对象时使用名值参数对设置属性,例如plot(1:10,1:10,'LineWidth',3)。大多数绘制图形函数都支持名值参数对,名值参数对也是常用的属性设置方法,可以一次赋予多个属性值。
用代码创建GUI大致可分为两大类,一类是基于uifigure函数创建,另一类是基于figure函数创建。图形对象有很多,包含放置对象的容器、坐标区、图窗工具、检测组件、可扩展组件,以及对话框和通用通知等。
基于figure函数创建的对象、布局、对话框和通知、控制流,以及App数据和预设见表1-2~表1-6。
表1-2 对象
序号 |
函数名 |
说明 |
---|---|---|
1 |
axes |
创建笛卡儿坐标区 |
2 |
uicontrol |
创建用户界面控件 |
3 |
uitable |
创建表 |
4 |
uipanel |
创建面板容器 |
5 |
uibuttongroup |
创建用于管理单选按钮和切换按钮的按钮组 |
6 |
uitab |
创建选项卡式面板 |
7 |
uitabgroup |
创建包含选项卡式面板的容器 |
8 |
uimenu |
创建菜单或菜单项 |
9 |
uicontextmenu |
创建上下文菜单 |
10 |
uitoolbar |
在图窗中创建工具栏 |
11 |
uipushtool |
在工具栏中创建按钮工具 |
12 |
uitoggletool |
在工具栏中创建切换工具 |
表1-3 布局
序号 |
函数名 |
说明 |
---|---|---|
1 |
align |
对齐用户界面控件和坐标区对象 |
2 |
movegui |
将图窗移动到屏幕上的指定位置 |
3 |
getpixelposition |
获取对象位置(以像素为单位) |
4 |
setpixelposition |
设置对象位置(以像素为单位) |
5 |
listfonts |
列出可用的系统字体 |
6 |
textwrap |
使用户界面控件的文本换行 |
7 |
uistack |
对用户界面控件的视图层叠重新排序 |
表1-4 对话框和通知
序号 |
函数名 |
说明 |
---|---|---|
警报 |
||
1 |
errordlg |
创建错误对话框 |
2 |
warndlg |
创建警告对话框 |
3 |
msgbox |
创建消息对话框 |
4 |
helpdlg |
创建帮助对话框 |
5 |
waitbar |
创建或更新等待条对话框 |
确认和输入 |
||
1 |
questdlg |
创建问题对话框 |
2 |
inputdlg |
创建收集用户输入的对话框 |
3 |
listdlg |
创建列表选择对话框 |
4 |
uisetcolor |
打开颜色选择器 |
5 |
uisetfont |
打开字体选择对话框 |
6 |
export2wsdlg |
创建用于将变量导出到工作区的对话框 |
文件系统 |
||
1 |
uigetfile |
打开文件选择对话框 |
2 |
uiputfile |
打开用于保存文件的对话框 |
3 |
uigetdir |
打开文件夹选择对话框 |
4 |
uiopen |
打开文件选择对话框并将选定的文件加载到工作区中 |
5 |
uisave |
打开用于将变量保存到.mat文件的对话框 |
打印和导出 |
||
1 |
printdlg |
打开图窗的“打印”对话框 |
2 |
printpreview |
打开图窗的“打印预览”对话框 |
3 |
exportsetupdlg |
打开图窗的“导出设置”对话框 |
其他 |
||
1 |
dialog |
创建空的模态对话框 |
2 |
uigetpref |
创建根据用户预设打开的对话框 |
表1-5 控制流
序号 |
函数名 |
说明 |
---|---|---|
1 |
uiwait |
阻止程序执行并等待恢复 |
2 |
uiresume |
恢复执行已阻止的程序 |
3 |
waitfor |
阻止程序执行并等待条件 |
4 |
waitforbuttonpress |
等待单击或按键 |
5 |
closereq |
默认图窗关闭请求函数 |
表1-6 App数据和预设
序号 |
函数名 |
说明 |
---|---|---|
1 |
getappdata |
检索应用程序定义的数据 |
2 |
setappdata |
存储应用程序定义的数据 |
3 |
isappdata |
确定应用程序数据是否存在,是则返回1(true),否则返回0(false) |
4 |
rmappdata |
删除应用程序定义的数据 |
5 |
guidata |
存储或检索用户界面数据 |
6 |
guihandles |
创建包含图窗的所有子对象的结构体 |
7 |
uisetpref |
管理uigetpref中使用的预设 |
本书在介绍对象属性的时候,如字体中的FontName、FontSize、FontWeight、FontAngle、FontUnits,交互性中的Visible、Enable、Tooltip、ContextMenu,回调执行控制中的Interruptible、BusyAction、BeingDeleted,以及标识符中的Tag、UserData等,由于其在不同对象中含义是一致的,因此在最先出现的时候会做详细介绍,后文不重复介绍。