首页 > 资讯 > 科技 > 正文
2024-03-01 14:07

图形用户界面 (GUI) 开发教程

写在前面

图形用户界面(user,GUI)实际上是人与计算机交互的界面显示格式。 从广义上讲,我用来阅读本文的浏览器也是一个 GUI。 读者可以通过这个浏览器获取信息,点击“最小化”、“窗口”和“关闭”按钮来实现自己想要的功能,并阅读浏览器中的文本。

我们常说做一个“软件”,但实际上,它很可能是一个实现与后端算法交互的接口。 因为绝大多数用户看不懂后端代码,而是想用这个算法来实现自己想要的功能,制作一个简洁、干净、易用、美观的GUI对于提高应用程序的适用性是非常有用的。后端算法。 必要的。

不可能开发一个项目,写好算法,直接交给用户说:“这里,这就是你想要的功能,简单改几个参数就可以实现你想要的功能!” 明显地! 不可行。 当用户看到代码的时候,会感到头晕,开始抗拒,怀疑我们的代码能力行不行?

例如。

程序员肖雷写了一套卡尔曼滤波算法。 当交付给用户时,它看起来像这样:

mode = 'IF'
% mode = 'UD';
% mode = 'FD';
% mode = 'FT1';
% mode = 'FT2';

告诉用户,“如果你想使用信息过滤,只需取消注释 mode = 'IF'!”

“如果你想使用UD过滤,只需取消注释mode='UD'即可!”

……

“但是不要忘记注释掉你不想使用的其他过滤算法,否则会出现错误!”

听完小雷的介绍,用户可能已经头晕了,可能不知道哪一行代码需要注释哪个算法。

或者更极端的是,小雷的代码编写不规范,变量名乱写,比如这样:

aaa = '1';
% aaa = '2';
% aaa = '3';
% aaa = '4';
% aaa = '5';

天知道哪一行对应哪种过滤算法! !

但是,如果您编写一个 GUI,例如如下所示的简单选择框,该怎么办:

添加了模式选择框

是不是清楚多了?

用户不必自己去看后端算法的代码,因为看久了也可能看不明白。 现在用户想使用什么过滤模式? 只需选择所需的过滤模式并单击“确定”即可。

然而这样的界面还不能满足用户的需求。

如果用户想自己改变算法参数怎么办? 想要改变仿真时长、初始状态、噪声矩阵……上面的选择框显然没有为用户提供合适的地方来改变算法参数。

于是小雷重新设计了界面,改为如下:

完成品

现在用户有很多选择。 您可以选择滤波模式、选择是否保存图片和数据、修改仿真参数,并展示不同滤波算法的核心原理公式,让用户直观、感性地了解。 从广义上讲,这可以用作软件。

用户很满意。

那么,如何开发这样的接口呢?

根据我自己的实践经验,以下是开发GUI的完整流程。 有些控件可能会被省略,没有引入,因为我感觉这些控件在我的开发过程中并没有用到。 但我认为使用控件的方法是相似的。 掌握了核心逻辑后,只需要在网上搜索另一个控件并学习经验,就可以很快掌握。

首先说明一下,这里所说的GUI都是指2018版本的GUI。 后续版本推出了APP功能,取代了原来的GUI。 但我常用的软件还是2018年的,所以我写的教程都是2018年的GUI开发教程。至于其他真正像“软件”的教程请看《PyQt5++安装、配置与使用》()。 使用QT,你可以制作一个像“软件”一样的软件。

以下是整个教程的顺序:

下拉式菜单;

单选按钮和复选框;

静态文本和可编辑文本;

轴;

团体;

进度条;

图形用户界面源代码。

图形化启动模式

打开并在命令行输入

guide;

得到如下图所示的界面。

GUI生成窗口

这里我们选择“New GUI”,点击第一项“Blank GUI()”,选择保存位置,点击“确定”。

之后会出现一个新的界面,如图所示。

默认GUI界面

按照图中的分区一一介绍功能。

分区“1”中常用的按钮是最后一个绿色三角形,用于设计完成后运行GUI并检查效果。 其他按钮不常用,无需花费精力。

分区“2”是控制区域,它提供了可以在 GUI 中使用的控件。 我们在设计GUI时,常用的控件主要有(按照从上到下、从左到右的顺序):

分区“3”描述了 GUI 的标记,该标记在() 操作中使用。

分区“4”描述了 GUI 中的当前鼠标位置以及所选控件的位置和大小。

按钮(按下)视图属性

选择功能区中的“按钮”标签并将其拖到 GUI 中。

按钮

步骤 1 和 2 非常简单。 第3步需要用左键双击“按钮”,弹出“检查器”窗口。

检验员非常重要。 大多数操作都是在检查器中完成的。

物业检查员

检查员有2种查看方式,红框内标注。 第一种是按功能分类列出,第二种是按字母顺序列出。 推荐使用第一种方法查看按钮的属性。 需要注意的属性并不多,只有4种,分别是:

美化按钮,可以得到如下图所示的按钮样式。

具有设置属性的按钮

其余的控件都是这样设置的。 这里以按钮为例进行说明。 后面介绍其他控件的时候就不再赘述了。

标签命名方式

我在这里告诉你如何设置标签。

将按钮拖入 GUI 后,标签默认为 。 这个标签不好,没有辨识度。 以后控件多了,就不知道哪个标签对应哪个功能了,所以需要添加一个标识,方便以后阅读代码。

我自己的习惯是使用下划线的方式来命名标签,即“标识”。 这里按钮的标签是,表示用于实现模拟的按钮。

其余控件的命名原则如下:

打回来

选择按钮,右键,选择“查看回调”,然后选择“”,就会生成相应的回调函数。

查看回调

将显示下面所示的代码。

打回来

这个功能非常重要。

这是我们想要开发的所有功能的实现地方。 因为一开始我对GUI很迷茫,如果想用GUI来实现功能,我不知道自己的逻辑该写在哪里。 后来查资料才发现——哦,需要在回调函数里写逻辑哦~

其他控件的逻辑也写在相应的回调函数中。 别忘了这一点。 后面就不讲如何获取其他控件的回调函数了。

一个小总结

总结一下,使用按钮(包括其他控件)的步骤分为3步:

将需要使用的控件拖拽到GUI中;

打开控件的检查器并根据需要设置属性;

写一个回调函数。

弹出菜单

下拉菜单和下拉列表()的功能类似,但下拉菜单更节省空间。 在项目GUI设计中,我习惯使用下拉菜单来实现多个选项的逻辑。

它在 GUI 中看起来像这样:

多选菜单界面

图中的“选项1”、“选项2”、“选项3”、“选项4”是在检查器中设置的。

弹出菜单设置

也就是文本中的属性,一个选项,一个回车键,这样就可以排列了。

界面关系图和工作流程图_用户界面关系图_界面关系图怎么画

设置完弹出菜单选项后,很重要的一步就是如何读取弹出菜单选项?

代码在这里:

mode_flag = get(handles.filter_ppmenu,'value');

您可以通过 get() 函数获取弹出菜单的值。 我这里给这个弹出菜单设置的标签是,代码的意思是获取句柄的值(value)。

获取弹出菜单的值后,可以使用()函数选择相应的操作。 代码如下:

switch mode_flag
 case 1
  % 想要实现的功能
 case 2
  % 想要实现的功能
 case 3
  % 想要实现的功能
 case 4
  % 想要实现的功能
 case 5
  % 想要实现的功能
end

注意,当=1时,实际上是默认选项的值,也就是弹出菜单选项的值。 =2 从您真正想要选择的选项的值开始。 这个很容易出错,所以要记住。

如果你害怕出错,你可以只写你想要选择的选项,而不在第一行添加任何弹出菜单值。

单选和复选框

单选按钮是一个可以选择的圆形按钮。 它通常用于实现与其他函数互斥的选择函数。

复选框形状为方形,通常用于实现多种功能选项的组合。

一般情况下,单选按钮选择后就无法取消,或者选择该选项后,其他选择的功能也被取消; 带有复选框,选择该功能后,可以继续选择其他功能,并且所选择的功能可以取消。

它们看起来如下图所示。

单选按钮和复选框

这两个盒子没有什么复杂的。 需要记住的重要一点是,它们在 GUI 中的作用是获取它们的值。 除了这个功能之外,其他功能还没有开发出来。

代码是:

% 单选框获取值的方式
xxx_rbtn_flag = get(handles.xxx_rbtn,'value');
% 复选框获取值的方式
xxx_cbox_flag = get(handles.xxx_cbox,'value');

静态文本(Text)和可编辑文本(Edit Text)

静态文本通常显示固定标签,可编辑文本可用于输入参数。 这就是两者功能上的区别。 他们分别看起来像这样。

静态文本和可编辑文本

如果将静态文本放入 GUI 中,则无需移动它。 你不需要担心它。 您需要担心的是可编辑文本。

获取可编辑文本中的文本,代码为:

xxx_edit_str = get(handles.xxx_edit,'string');
xxx_edit = str2double(xxx_edit_str);
% xxx_edit = str2num(xxx_edit_str);

这里的属性不能使用值。 必须使用它,因为在可编辑文本中获得的字符 ()。

如果要在可编辑文本中使用数值,则需要先将字符转换为数值,使用 () 或 () 来实现。

您还可以在可编辑文本中设置该值。 一种方法是直接在可编辑文本框中设置。 另一种方法是编写代码,如下:

set(handles.xxx_edit,'string','Hello, world!');

这样您就可以设置可编辑文本的代码。

Axis通常用于绘制模拟曲线或插入图片。

轴接口

在之前的项目中,我使用坐标轴来绘制算法仿真曲线。 代码是:

axes(handles.xxx_axes);
plot(xxx);

如果要清除轴上的绘图,可以使用以下代码。

axes(handles.xxx_axes);
cla;

可以看到,无论是绘制模拟结果还是清除结果,都必须先使用axes(.)。 这行代码的意思是指定对应的轴。 如果GUI中有很多轴,并且没有指定对应的轴,GUI将不知道要操作哪个轴。

轴的另一个用途是插入图片,代码为

axes(handles.xxx_axes)
image(imread('xxx.png'));
axis off;

第一行代码指定对应的轴。

第二行代码插入相应的图像。

第三行代码取消轴的轴显示。

我这里遇到了一个未解决的问题,就是将上面的代码写在()中,再次打开GUI的.fig文件时,该轴对应的标签就会消失。 如果其他控件下的()中写的是上面的代码的话,就不会有这样的问题。

因此,您可以使用坐标轴来插入图片并为GUI制作背景。 首先提前规划GUI各部分的用途,用PS制作一个简单的背景,如下图。

添加背景后的界面

它比没有背景的 GUI 更好看吗? 可以花点心思绘制背景,这样可以提高GUI的美观度。

团体

组通常用于容纳其他控件。 所有实现相同角色或实现相同对象功能的控件都可以放置在一个组中。 操作时只需对群组进行操作即可。

控制板

组(又名面板)与上面的面板类似,一组中包含一个对象,多个组中包含多个对象。 这可以提高效率,因为无需重新调整每个对象的控件。 初始组调整完毕后,后续组只需要ctrl+c、ctrl+v即可。

进度条(Bar)

进度条起到提醒的作用,告诉用户算法当前进行到哪一步,需要多长时间才能结束,让用户知道该做什么,不用担心。

进度条是一个非常重要的控件!

没有进度条,用户不知道算法的状态。 他们可能会变得不耐烦并关闭 GUI。 但这很容易使计算机崩溃。

生活中即使我们做了很多事情,如果没有进度条,我们也不知道情况如何,很容易放弃。

使用进度条的代码是:

h = waitbar(1,'算法仿真中......','name','目标跟踪仿真软件');

进度条

解释一下上面的代码。

如果想让进度条显示百分比,可以使用下面的代码:

h = waitbar(0,'算法仿真中......','name','目标跟踪仿真软件');
for i = 1:nt-1
 per_str = fix(i/nt*100);
 str = ['算法仿真中......',num2str(per_str),'%'];
 waitbar(i/nt,h,str);
end
close(h);

如果想简单一点,让进度条移动而不显示百分比,可以使用下面的代码:

h = waitbar(0,'算法仿真中......','name','目标跟踪仿真软件');
for i = 1:nt-1;
 waitbar(i/nt);
end
close(h);

close(h)表示用句柄h关闭进度条。 不然以后画图的时候会误画在进度条上,或者出现其他奇怪的错误。

GUI设计成品

好了,需要教的知识都教完了,下面开始实战吧!

下面的GUI是添加了数亿细节的成品,请参见vcr。

源码放在这里,供大家按需使用,https:\..io\\\files-2024-01-22\se_v1.0.zip。 我的是2018b版本,其他版本不保证正常使用。

该GUI实现的功能有:

过滤器和目标状态参数输入功能。

保存数据功能;

保存仿真结果图形功能;

根据不同的滤波算法显示对应的滤波公式功能;

执行模拟功能;

退出软件功能。

数据保存功能可以通过带今日日期和不带今日日期两种格式来实现,如下图所示。

数据保存功能

这样,不同时间保存不同的滤波算法和仿真数据。

通过保存图片功能得到的图片如下图所示。

图片保存功能

仿真结果按照不同的滤波器、不同的功能保存。

GUI所在文件夹进行了适当美化,文件根据不同的功能存放在不同的文件夹中,如下图所示。

GUI代码界面

这样用户在打开GUI时就不会看到杂乱的文件夹,反而会干净、更加美观,这样写代码也会更加优雅。

终于

欢迎通过电子邮件联系我:

来信时请注明您的身份,否则我们将不予回复。