图形界面
这一节学习如何使用matlab来撰写图形界面程序. 首先在命令行窗口中输入guide
, 打开matlab内置的GUi程序撰写的工具, 该工具类似于C#窗体设计工具一样, 是一个可视化的操作工具. 在快速开始界面选择默认模板, 可以根据需要调整程序的保存位置, 点击确定即可进入UI设计界面.
左侧的按钮列出了可以使用的基本元件. 可以通过设置使其显示相应的名称. 依次点击文件
->预设
-> GUIDE
->在组件选项板中显示名称
, 点击应用
, 点击确定
, 即可在设计界面中显示组件的名称, 方便初次学习时对组件的识别. 设置中还有许多其它选项, 可以自行探索, 并根据需要做相应的修改. 左侧的组件在初次学习时很难全部介绍到, 这篇文章只做简单的示例. 下面提供一些关于这些组件信息的文档超链接, 可以根据需要进行查阅.
- Push Button: 普通按钮
- Slider: 滑块
- Radio Button: 单选按钮
- Check Box: 复选框
- Edit Text: 编辑文本
- Static Text: 静态文本
- Pop-Up Menu: 弹出式菜单
- List Box: 列表框
- Toggle Button: 切换按钮
- Table: 表
- Axes: 坐标区
在GUI程序设计界面中, 网格状区域代表的是设计的最终程序的窗体大小, 可以通过鼠标拖动的方式, 把左侧控件拖至画布区域. 网格状的区域可以自己根据需要拖动画布右下角来调整大小. 这里首先拖动一个坐标轴和三个按钮, 以作为后面内容的示例.
点击右上角的绿色三角, 即可运行当前GUI程序, 在运行之前, matlab会提示保存, 设置名字保存即可.这名字设置为gui1
, 保存后的运行结果如下:
此时观察matlab的工作文件夹可以发现, 此文件夹中增加了两个文件, 分别是gui1.m
和gui1.fig
, 可以理解为gui1.fig
文件存储的是图形界面,比如按钮的位置,大小等等参数. 而与之对应的gui1.m
文件来存储这个GUI程序的相关操作算法 , 也就是程序的行为.
目前, 我们的程序三个按钮排列不是很整齐, 想要对齐按钮, 可以使用两种方式. 第一种方式采取手动的方式, 在界面设计时, 利用网格线使按钮对齐, 即把按钮放在同一横线或竖线区域. 第二种方式是利用matlab的内置工具, 首先选中要对齐的三个按钮, 点击菜单栏中的工具
选择对齐对象
, 会弹出对齐对象的设置弹窗, 在弹窗中设置对齐方式, 点击应用, 点击确定即可.
下面介绍一些关于按钮的相关属性以及修改方式. 可以通过鼠标双击元件, 打开元件的检查器, 里面列出了关于这个元件的属性和属性值, 可以根据需要做响应修改. 这里以修改按钮的显示文本为例, 目前我的程序上三个按钮都显示的 按钮两个字 , 为了加以区分, 应该让不同的按钮显示不同的文本. 首先鼠标双击第一个按钮, 在 String
属性修改其属性值, 这里将其改为按钮1, 点击确定即可. 但是需要注意的是, 此处修改的只是这个按钮的显示文本, 并不是这个按钮组件的id
, 也就是说在程序设计时对这个按钮做控制时应该使用的按钮的唯一标识码并没有变. 那么这个按钮的唯一标识是什么呢? 在检查器中找到Tag
属性, 其属性值就是这个按钮的唯一标识, 这里显示的是pushbutton4
(由于我删除了原来的三个按钮, 又拉了三个新的按钮, 所以此处显示的不是pushbutton1而是pushbutton4).
也可以尝试对其他属性进行修改, 修改方式都是一样的.
下面学习怎么写GUI程序的脚本文件, 也就是对当前GUI程序做一些行为上的内容编写. 前面已经介绍过, 对程序行为进行编写要在M文件中进行, 首先双击gui1.m
来打开文件, 观察文件的初始内容可以发现, 文件中包含了许多的function
, 对于程序行为的编写 主要就是编写这些function
中的内容. 首先找到gui1_openingFcn
这个函数, 根据函数名称的语义可以了解到这是我的整个的GUI程序的初始化函数 , 我们在其中加入下面一段绘图代码, 即可是在启动时直接显示我们绘制的图像.
以我的理解, matlab中GUI程序的根对象是 handles
, 因此下面的程序代码中许多变量都写成handles.
1 | handles.peaks=peaks(35); |
保存后运行程序, 即可看到我们想要的结果.在窗体弹出时, 就绘制了一个图像.
上面介绍了在初始化函数中插入代码进行绘图, 对于程序的行为设计大致的步骤就是这样. 下面介绍如何通过点击按钮画图. 每一个按钮都有一个callback
函数, 这个函数就是在一直检查当前的按钮有没有被按到, 如果检测到有按按钮的动作, 就执行这个函数中的内容. 前面已经提到过, 我目前的按钮1的tag
属性是pushbutton4
, 也就是说, 我要先找到pushbutton4的callback函数, 把上面的绘图代码剪切到这个函数内, 保存后运行程序, 我们就实现了通过点击按钮1 实现绘制图像的功能.
对下面两个按钮也做如此操作, 我们就可以实现不同的按钮画不同的图形.
但是我们上面给出的代码中, 没有指定图形画在哪个坐标轴上, 如果我的GUI程序有两个坐标轴的话, 他会画在哪个坐标轴呢? 首先再拉一个坐标轴到画布, 保存后运行, 观察结果.
可以看到, 图像被画在了第二个坐标轴, 其实在matlab中, 许多没有指定操作对象的操作, 都会被默认为当前对象, 在前面学习的图形绘制的课程中, 对图像的一些属性做修改时, 不指定修改的是哪副图像, 也会被默认为最后绘制的一幅图像, 也就是当前的图像. 在此处也是这个机制, 因为我们最后添加的是第二个坐标轴, 所以第二个坐标轴是活跃的对象, matlab对于没有指定对象的绘图操作, 在当前最新的坐标轴中执行. 那么衍生的问题来了, 该如何指定在第一个坐标轴中绘制呢? 可以通过两种方式来指定绘图的坐标轴, 下面给出两种方式修改后的代码:
1 | handles.peaks=peaks(35); |
或者
1 | handles.peaks=peaks(35); |
练习: 撰写一个GUI程序, 其中包含两个滑动条和一个静态文本元件, 分别用滑动条的位置表示一个变量的取值, 范围是0到100之间, 文本显示这两个值的和.
结果图示例:
提示: 可以使用
get()
函数和set()
函数获取和设置元件的属性值, 例如:
1
2 a = get(handles.slider1, 'Value');
set(handles.text2, 'String', 'TEST');可能会用到的函数有
get()
set()
int16()
num2str()
需要说明的是, 上述练习代码中的变量都是局部变量, 只在其对应的函数内生效. 那么如何在函数间进行值的传递呢? 其实方法和使用全局变量进行函数间值的传递类似, 只不过这里有根对象handles
, 我们可以利用handles
来在函数间进行值的传递. 例如:
1 | handles.myData = a; % 把局部变量a存在handles下的mydata中 |
目前为止, 我们的matlab GUI程序已经编写完成, 但是还存在一个小缺陷, 对于没有安装matlab的电脑来说, 无法运行我们编写的程序, 对此, matlab中提供了编译指令, 使用deploytool
来把我们的matlab中的GUI程序封装成.exe
的windows可执行文件, 这样, 我们的程序就可以在任何一台windows电脑中运行.
首先命令行窗口输入deploytool
, 在弹出窗口中选择 Application Compiler
工具的窗口页面如下:
点击加入主要文件, 选择我们刚才编写的GUI程序. 加入gui2.m
文件即可, 这个工具会为我们自动寻找和创建一些相关文件.
下一步点击package
即可生成可执行文件.
打包完成后, 会自动打开文件夹, 我们可以在for_testing
目录下找到gui2.exe
文件并双击打开.
其效果与在matlab中运行没有任何区别.