本文主要记录如何用MATLAB自带的GUI功能做一个绩点计算界面。并以此来简单介绍一下MATLAB GUI的使用过程。完整代码见:https://github.com/ZhouJiaHuan/compute-GPA-master
启动guide工具箱
guide是MATLAB用来制作GUI界面的工具性,我们只要在MATLAB命令窗口中输入命令guide即可打开GUI制作界面,如下图:
在新建GUI这一栏中提供了几种常用的界面,这里我们直接选用BLANK空白界面即可。
这样就会生成一张初始的空白界面,我们可以直接点击工具栏中绿色的运行按钮看一下初始界面的效果。
文件名保存为test.fig,点击运行后,发现一共生成了两个文件,一个是界面文件test.fig,另一个是对应的test.m文件。test文件中保存的就是界面文件中的所有信息。一般我们制作GUI界面分成2个步骤:(1)设计GUI界面,即在界面上添加一些我们需要的控件等;(2)写回调函数,简单的说,每一个控件被添加到界面上肯定是有其特定的功能(显示信息、按钮操作等)。比如你想通过按一个按钮去执行特定的功能,这个时候你就把需要执行的代码写在按钮的回调函数里。
一个简单GUI示例
为了帮助理解这个过程,我们先来建立一个简单的GUI来介绍:要求在界面上放置1个按钮,和3个文本框,其中两个文本框用来输入两个数,当按下按钮的时候,计算两个数的和并显示在第三个文本框中。
我们现在刚刚的空白界面上添加几个控件(3个文本框和1个按钮),直接从左侧的控件中拖过来即可。如下图所示:
文本框中默认显示是内容是“可编辑文本”,我们可以通过双击控件来修改该控件的属性,这里我们先修改第一个文本框的属性:
上图中我分别修改了3个属性:将显示的字体设为20号、将默认显示的字符串设为“0”、
这里需要重点注意的是Tag属性,它每个控件的句柄名,可以理解为每一个控件的名字,在下面写回调函数的时候,都需要通过Tag属性的值来传递数据,因此,所有控件的Tag属性内容不能相同。
按照相同的方法我们依次修改剩下来的控件的属性,并添加一些静态文本增强可读性:
以上只是简单地把界面做好了,为了实现我们需要的功能,还需要写回调函数,我们再想一下我们需要实现的功能:按下求和按钮后,计算两个数的和,最后显示在文本框中。因此,我们只需要写求和按钮的回调函数,并读取两个文本框中的信息,然后把计算的结果传递到第三个文本框中。
这里需要介绍GUI中用于传递数据的函数:set()和get()。set()函数用于修改某个控件的属性值。比如我想把Tag名为“add1”的文本框的显示内容改成“1”,可以通过下面的代码实现:
1 | set(handles.add1, "string", 1) |
同样,我们如果想要获取一个Tag名为“add1”的文本框内容,可以通过get()实现:1
num1 = str2num(get(handles.add1, "string"))
由于获取到数据的类型是string格式的,在计算的时候需要转换。因此用str2num()完成转换过程。
在了解了set()和get()的基本用法,下面我们就来看看求和按钮的回调函数怎么写。
右击求和按钮选择查看回调,继续选择Callback,会打开test.m文件,并自动创建回调函数,如下图:
回调函数的名字是根据控件的Tag属性创建的,由于我求和的Tag属性是“add”,因此对应的回调函数名字叫“add_Callback”
在函数体中添加如下代码:1
2
3
4num1 = str2num(get(handles.add1, 'string'));
num2 = str2num(get(handles.add2, 'string'));
result = num1 + num2;
set(handles.sum, 'string', result);
运行测试结果:
大功告成,还是很简单的吧,下面我们就步入正题,制作我们计算绩点的界面吧!
绩点计算工具
第一步当然还是设计界面,如下:
界面上的控件主要有两类,右侧是一组按钮,中间是需要显示是成绩单信息。我们期望的功能如下:
- 点击导入成绩表,会打开文件浏览器,查找本地的成绩表并导入,同时在中间显示基本的信息;
- 点击计算绩点,按照指定的绩点计算方法计算绩点,计算成功后弹出提示信息;
- 点击导出结果,保存计算好的绩点并保存到本地的表格中;
- 点击退出,退出程序
下面我们就依次编写4个按钮的回调函数:
导入成绩表:
1 | % --- Executes on button press in Load_score. |
这里需要注意的是,成绩表需要满足读取的格式,如下:
课程需要满足格式:课程名/类型/学分
计算绩点
1 | % --- Executes on button press in Compute_GPA. |
函数中调用了另外两个函数,分别定义如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22function [course, credit] = get_course_credit(RAW)
% Function:
% 读取表格数据中学生信息(包括学号和姓名)
% Input
% RAW: 课程成绩表,第一行为表头,前两列分别为学号和姓名,成绩从第三列开始;
% 学号|姓名|课程1/必修课/学分1|课程2/必修课/学分2|
% ** | ** | ** | ** |
% ** | ** | ** | ** |
% ** | ** | ** | ** |
% Output
% course: (1,n),cell类型,存放所有的课程名(n门课程)
% credit: (1,n),double类型数组,存放所有课程对应的学分
num_course = size(RAW,2)-2; % 不包含前两列(学号、姓名)
course = null(num_course);
credit = null(num_course);
for i = 1:num_course
course_name_credit = RAW{1,i+2}; %课程/必修课/学分
course_credit = regexp(course_name_credit,'/','split'); %切分
course{i} = course_credit{1}; % 课程名
credit(i) = str2double(course_credit(end)); % 学分
end
1 | function [GPA,GPA_per_course] = compute_GPA(NUM,credit) |
导出结果
1 | % --- Executes on button press in Write_to_xls. |
代码中调用了Sort_result()函数来对结果进行排序,具体的定义如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28function sorted_result = Sort_result(RAW, GPA)
% Function:
% 对绩点按降序排序并保存
% Input
% RAW: 课程成绩表,第一行为表头,前两列分别为学号和姓名,成绩从第三列开始;
% 学号|姓名|课程1/必修课/学分|课程2/必修课/学分|
% ** | ** | ** | ** |
% ** | ** | ** | ** |
% ** | ** | ** | ** |
% GPA: (m,1),double类型,绩点
% write_to_xls:0或1,表示是否导出xls文件
% Output
% sorted_result: cell类型,排序结果,[排名,学号,姓名,绩点]
[id, name] = get_id_name(RAW);
num_stu = length(name);
rank = 1:num_stu; rank = rank';
name_sorted = null(num_stu,1);
id_sorted = null(num_stu,1);
[GPA_sorted,Index] = sort(GPA,'descend');
for i = 1:num_stu
id_sorted{i,1} = id{Index(i)};
name_sorted{i,1} = name{Index(i)};
end
title = {'排名', '学号','姓名', '绩点'};
sorted_result = [title;
num2cell(rank),id_sorted,name_sorted,num2cell(GPA_sorted)];
1 | [id, name] = get_id_name(RAW); |
退出
1 | % --- Executes on button press in Quit. |
最后看一下最终的效果:
写在最后的话:
感谢你一直读到这里,希望本篇博客对你有点帮助。关于本篇博客中的任何问题欢迎指出,虚心接受各位大佬的教导!