MATLAB 图形用户界面(GUI)创建指南
1. 引言
如今,大多数计算机程序都采用了图形用户界面(GUI),实际上,MATLAB 的桌面环境就是一个 GUI。只要你能通过点击图标来执行操作,就是在使用 GUI。在 MATLAB 中创建自己的 GUI 很容易,特别是使用 GUIDE 界面时,但这需要你了解一些编程基础知识,比如:
- 结构数组
- 子函数
- 图形对象名称(句柄)的使用
GUIDE 程序创建的 M 文件使用结构数组在程序各部分之间传递信息。每个部分都是一个子函数,GUI 的组件作为图形对象的属性存储,使用句柄图形。
一般来说,创建 GUI 的第一步应该是仔细规划它的功能和外观。提前规划能避免很多麻烦。接下来,我们将逐步开发 GUI,以便专注于程序的工作原理。阅读时,建议你尝试运行相关命令。
2. 简单的单用户交互 GUI
2.1 创建布局
要开始创建 GUI,有两种方式启动 GUIDE 程序:
- 从 MATLAB 工具条中选择“New > App > Graphical User Interface”。
- 在命令行输入“guide”。
之后会打开 GUIDE 快速启动窗口,若要开始新项目,选择窗口左侧列表中的“Blank GUI”模板。选择后,会打开一个名为 GUIDE 布局编辑器的新图形窗口,你可以通过选择网格的左下角来调整其大小。若希望 GUI 比图形窗口大,可先调整图形窗口大小。
创建按钮、文本框和图形窗口的布局时,使用窗口左侧组件面板中的图标。默认图标显示紧凑,但对新用户不够直观。若要将工具面板改为项目名称列表,操作如下:
- 选择“file > preferences > GUIDE”。
- 勾选“Show names in component palette”。
下面创建一个简单的 GUI,用于输入多边形的边数,并在极坐标中绘制该多边形。此 GUI 需要三个组件:坐标轴、静态文本框和编辑文本框。从组件面板中选取这些组件并按需求排列。
若要修改设计元素的属性,可使用属性检查器。以静态文本框为例,操作步骤如下:
- 选择静态文本框,右键单击,选择“Property Inspector”。
- 也可从菜单栏选择“view > property Inspector”。
在属性检查器中,可更改显示消息的字体、文本框颜色等。最重要的是字符串属性,将其从“Static Text”改为“Enter the number of sides”。对“edit text”框进行同样操作,删除默认文本。
完成后,点击窗口工具栏中的“Save and Run”图标(绿色三角形按钮),会提示输入项目名称,如“polygon_gui.fig”。运行文件后,GUIDE 窗口名称会改变,同时会创建一个 MATLAB 脚本“polygon_gui.m”。
2.2 为程序添加代码
直接打开程序解读代码会很困难,因为 M 文件是一个包含多个子函数的函数。部分子函数用于创建“polygon_gui.fig”窗口中的图形,部分用于添加用户与 GUI 交互时触发操作的代码。
若要查看“polygon_gui.m”文件中的函数列表,点击工具栏上的“Go To”图标。用户应修改的函数有:
- gui_name_OpeningFcn
- graphics_object_name_Callback
在“polygon_gui”文件中对应的是:
- polygon_gui_OpeningFcn
- edit1_Callback
在更复杂的 GUI 中,布局上的每个图形对象都有一个回调函数,用户可通过点击相关函数定位到对应代码部分。也可在布局编辑器中,右键单击图形对象(如编辑文本框),选择“View Callbacks”,再选择“Callback”,将光标移到“edit1_Callback”子函数。
“edit1_Callback”子函数代码如下:
function edit1_Callback(hObject, eventdata, handles)
% hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB®
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit1 as text
% str2double(get(hObject,'String')) returns contents of edit1 as a double
该子函数有三个输入,“hObject”是将子函数与编辑文本框关联的图形句柄,“eventdata”是 Mathworks 为软件后续版本预留的占位符,“handles”是用于在子函数间传递信息的结构数组。
用户在文本框中输入的信息以字符串属性形式存储,若要将其作为数值使用,需将字符数组转换为双精度类型。可使用“str2num”或“str2double”函数。在“edit1_callback”子函数中添加以下代码:
sides = str2double(get(hObject,'String'))
然后添加代码绘制多边形并标注图形:
theta = 0:2*pi/sides:2*pi;
r = ones(1,length(theta));
polar(theta,r)
title('A polygon')
运行 GUI 时,点击“Save and Run”图标,在编辑窗口输入值(如 3)并按回车键,“edit1_callback”函数将执行并绘制多边形。
另一个需要修改的子函数是“OpeningFcn”,它在 GUI 首次运行时执行,可控制图形窗口在用户输入数据前的外观。为使“polygon_gui”显示与极坐标图一致的坐标轴系统,在“polygon_gui_OpenFcn”中添加创建空白极坐标图的代码:
function polygon_gui_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB®
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to polygon_gui (see VARARGIN)
% Choose default command line output for polygon_gui
handles.output = hObject; % Not necessary for this example
运行“polygon_gui.m”时,原始图形窗口将包含极坐标图坐标轴系统。
3. 多用户交互的图形用户界面 - ready_aim_fire
创建一个更复杂的 GUI 并不难,例如绘制从大炮发射的弹丸轨迹的 GUI。弹丸轨迹取决于发射角度 $u$ 和初始速度 $V_0$,水平和垂直距离的计算公式如下:
$h = tV_0 \cos(u)$
$v = tV_0 \sin(u) - \frac{1}{2}gt^2$
其中,$t$ 是时间(秒),$V_0$ 是初始速度(米/秒),$u$ 是发射角度(弧度),$g$ 是重力加速度($9.81 m/s^2$)。
创建此 GUI 的布局需要以下组件:
|组件|用途|
| ---- | ---- |
|Axes|用于绘图|
|Edit textbox|用于输入角度|
|Edit textbox|用于输入初始速度|
|Push button|用于“发射”大炮|
|Static textbox|用于标注角度文本框|
|Static textbox|用于标注速度文本框|
|Panel|用于将文本框分组|
从组件面板中选择相应项目创建布局,使用属性编辑器的字符串属性修改静态文本框、编辑文本框和按钮的内容。将两种文本框拖到面板上,通过标题属性更改面板名称。
当 GUI 有多个组件时,根据默认名称查找对应的回调函数较困难。例如,两个编辑文本框默认名为“edit1”和“edit2”,缺乏描述性。可使用属性编辑器中的标签属性更改名称,如将发射角度编辑文本框的标签从“edit1”改为“launch_angle”,初始速度编辑文本框的标签从“edit2”改为“launch_velocity”,按钮的标签改为“fire_pushbutton”。完成后,点击“Save and Run”按钮保存布局编辑器内容并命名为“ready_aim_fire”,会生成一个包含 GUI 的“fig”文件和一个包含代码的“M”文件。
为该 GUI 程序添加代码的步骤如下:
1. 找到“launch_angle_Callback”子函数,可通过以下两种方式:
- 选择 MATLAB 程序编辑器工具栏中的“Show functions”图标。
- 右键单击发射角度编辑文本框,导航到“launch_angle”回调。
- 添加代码:
handles.theta=str2double(get(hObject,'String'));
guidata(hObject, handles);
- 对“launch_velocity”回调进行类似修改,添加代码:
handles.vel=str2double(get(hObject,'String'));
guidata(hObject, handles);
- 当点击“Fire”按钮时绘制图形,因此在“fire_pushbutton”回调函数中添加绘图代码:
time=0:0.001:100;
h=time*handles.vel*cosd(handles.theta);
v=time*handles.vel*sind(handles.theta)-1/2*9.81*time.^2;
pos=find(v>=0);
horizontal=h(pos);
vertical=v(pos);
comet(horizontal,vertical);
创建的“time”数组步长较小,在绘图步骤中很重要。计算水平和垂直距离后,使用“find”函数找出“v”数组中所有正值的索引,定义新变量“horizontal”和“vertical”并使用“comet”函数绘图。“comet”函数可绘制弹丸轨迹,通过控制时间值的数量可改变绘图速度。
点击“Save and Run”图标运行程序,输入一组值后的结果如图所示。
4. 改进的 ready_aim_fire 程序
多次运行“ready_aim_fire”程序后,可能需要进行一些修改。例如,每次运行 GUI 时,绘图会调整大小以填满整个窗口,难以判断参数变化的结果。可修改“OpeningFcn”函数创建一个固定的坐标轴系统,同时添加一个目标,方便练习射击。
在“OpeningFcn”函数中添加以下代码:
plot(275,0,'s','Markersize',10,'MarkerFaceColor','r')
text(275,50,'target')
axis([0,1000,0,500])
hold on
第一行代码在 $x = 275$ 和 $y = 0$ 处绘制一个正方形点,调整其大小和颜色以便查看。第二行代码为目标添加标签。“axis”函数设置绘图的坐标轴范围,“hold on”命令使后续绘图在同一图形上进行,不擦除现有线条。
此版本的“ready_aim_fire”GUI 存在一个问题:若要重新开始并清除屏幕,需完全关闭它。可通过添加一个额外的按钮来重置绘图,步骤如下:
1. 返回 GUIDE 布局编辑器,添加一个额外的按钮。
2. 使用属性检查器的字符串属性将按钮标签设为“Reset”。
3. 使用属性检查器的标签属性将按钮及其关联函数的名称改为“reset_pushbutton”。
4. 点击“Save and Run”图标保存更改并更新“ready_aim_fire”程序。
5. 找到“reset_pushbutton_Callback”子函数,添加以下代码:
hold off
plot(275,0,'s','Markersize',10,'MarkerFaceColor','r')
text(275,50,'target')
axis([0,1000,0,500])
hold on
这段代码先关闭“hold”函数,然后重复“OpeningFcn”函数中的指令。在修改代码时,还可在“OpeningFcn”函数和“reset_pushbutton”回调中添加标题和坐标轴标签:
title('Projectile Trajectory')
xlabel('Horizontal Distance, m')
ylabel('Vertical Distance, m')
综上所述,通过以上步骤和代码,我们可以创建简单和复杂的 GUI,并对其进行优化和改进,以满足不同的需求。在实际应用中,可根据具体情况灵活调整代码和布局,实现更强大的功能。
MATLAB 图形用户界面(GUI)创建指南
5. 总结与操作流程回顾
为了更清晰地理解整个 MATLAB GUI 创建过程,下面对前面的操作流程进行总结。创建 GUI 主要分为以下几个关键步骤:
| 步骤 | 操作内容 |
|---|---|
| 启动 GUIDE | 可从 MATLAB 工具条选择“New > App > Graphical User Interface”,或在命令行输入“guide” |
| 选择模板 | 在 GUIDE 快速启动窗口选择“Blank GUI”模板开始新项目 |
| 设计布局 | 使用组件面板中的图标创建按钮、文本框和图形窗口等布局,可通过属性检查器修改组件属性 |
| 添加代码 |
找到对应的回调函数(如
OpeningFcn
、
Callback
等),根据需求添加代码实现功能
|
| 运行与测试 | 点击“Save and Run”图标保存并运行程序,测试 GUI 的功能 |
下面是一个 mermaid 格式的流程图,展示了创建简单 GUI 的主要流程:
graph LR
A[启动 GUIDE] --> B[选择 Blank GUI 模板]
B --> C[设计布局]
C --> D[修改组件属性]
D --> E[添加代码到回调函数]
E --> F[保存并运行程序]
6. 常见问题及解决方案
在创建 MATLAB GUI 过程中,可能会遇到一些常见问题,以下是一些问题及对应的解决方案:
| 问题 | 解决方案 |
|---|---|
| 找不到回调函数 | 可通过选择 MATLAB 程序编辑器工具栏中的“Show functions”图标,或在布局编辑器中右键单击图形对象,选择“View Callbacks”来定位 |
| 输入的字符串无法正确转换为数值 |
使用
str2double
或
str2num
函数将字符串转换为数值类型
|
| 绘图窗口大小不合适 |
可在
OpeningFcn
函数中使用
axis
函数设置坐标轴范围,固定绘图窗口大小
|
| GUI 运行后无法重置 | 添加一个“Reset”按钮,在其回调函数中添加重置绘图的代码 |
7. 拓展应用与实践建议
掌握了 MATLAB GUI 的基本创建方法后,可以进行一些拓展应用。例如,可以结合更多的 MATLAB 函数和工具箱,实现更复杂的功能,如数据处理、图像处理等。
以下是一些实践建议:
-
多尝试不同的组件组合
:通过尝试不同的组件组合,可以创建出功能丰富、界面美观的 GUI。
-
学习更多的回调函数用法
:回调函数是实现 GUI 交互功能的关键,深入学习回调函数的用法可以让你的 GUI 更加灵活。
-
参考优秀的 GUI 示例
:可以参考一些优秀的 MATLAB GUI 示例,学习它们的设计思路和代码实现方法。
8. 示例代码汇总
为了方便大家参考,下面汇总了前面提到的主要示例代码:
简单单用户交互 GUI -
polygon_gui
% edit1_Callback 子函数
function edit1_Callback(hObject, eventdata, handles)
% hObject handle to edit1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB®
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit1 as text
% str2double(get(hObject,'String')) returns contents of edit1 as a double
sides = str2double(get(hObject,'String'));
theta = 0:2*pi/sides:2*pi;
r = ones(1,length(theta));
polar(theta,r);
title('A polygon');
% polygon_gui_OpeningFcn 子函数
function polygon_gui_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB®
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to polygon_gui (see VARARGIN)
% Choose default command line output for polygon_gui
handles.output = hObject; % Not necessary for this example
多用户交互 GUI -
ready_aim_fire
% launch_angle_Callback 子函数
function launch_angle_Callback(hObject, eventdata, handles)
handles.theta=str2double(get(hObject,'String'));
guidata(hObject, handles);
% launch_velocity_Callback 子函数
function launch_velocity_Callback(hObject, eventdata, handles)
handles.vel=str2double(get(hObject,'String'));
guidata(hObject, handles);
% fire_pushbutton_Callback 子函数
function fire_pushbutton_Callback(hObject, eventdata, handles)
time=0:0.001:100;
h=time*handles.vel*cosd(handles.theta);
v=time*handles.vel*sind(handles.theta)-1/2*9.81*time.^2;
pos=find(v>=0);
horizontal=h(pos);
vertical=v(pos);
comet(horizontal,vertical);
% ready_aim_fire_OpeningFcn 子函数
function ready_aim_fire_OpeningFcn(hObject, eventdata, handles, varargin)
plot(275,0,'s','Markersize',10,'MarkerFaceColor','r');
text(275,50,'target');
axis([0,1000,0,500]);
hold on;
title('Projectile Trajectory');
xlabel('Horizontal Distance, m');
ylabel('Vertical Distance, m');
% reset_pushbutton_Callback 子函数
function reset_pushbutton_Callback(hObject, eventdata, handles)
hold off;
plot(275,0,'s','Markersize',10,'MarkerFaceColor','r');
text(275,50,'target');
axis([0,1000,0,500]);
hold on;
title('Projectile Trajectory');
xlabel('Horizontal Distance, m');
ylabel('Vertical Distance, m');
通过以上的总结、问题解决和拓展建议,希望能帮助大家更好地掌握 MATLAB GUI 的创建方法,在实际应用中能够灵活运用,开发出满足需求的 GUI 程序。不断实践和探索,你将能够发现更多有趣和实用的功能。
超级会员免费看
11

被折叠的 条评论
为什么被折叠?



