matlab app 学习笔记:新建选项卡组TabGroup、面板Panel、按钮Button、表UITable
在的基础上,本篇介绍选项卡组TabGroup、面板Panel、按钮Button、表UITable及其部分属性。打开第一篇中的app_01可视化对象。
在第一篇的基础上,本篇介绍选项卡组TabGroup、面板Panel、按钮Button、表UITable及其部分属性。
打开第一篇中的app_01可视化对象。
新建对象
新建选项卡组TabGroup
从左侧组件库中选择选项卡组并拖拽到设计视图区域,将选项卡组的大小调整到与appUIFigure一样大(手动拉即可,也可以设置Position实现)。在组件资源区会出现app.TabGroup在app.appUIFigure下面。
我们将app.TabGroup的第一个Tab改为Tab_projects(组件资源目录中双击修改),选中第一个Tab,将其Title属性改为 项目管理。第二个Tab改为Tab_datamanage,将其Title属性改为数据管理。改好后的效果如图。



新建面板Panel
选中Tab_projects,将其置为当前tab,从左侧选择面板并拉入设计视图中,放在Tab_projects的最上部,我们把它作为设置区域,后续放置按钮等组件(类似于office中的Ribbon)。将其大小调整到下图所示大小。将其名称改为app.Panel_projects,删除Title属性的内容回车(Title是一种提示标签,方便我们识别panel中的对象,对他们可以取一个有共性的名字,我们这里不用,所以删除)。


新建 按钮Button
从左侧拉去按钮到app.Panel_projects左侧,将其改为app.Button_newprohject,将其Text属性改为 新建项目。在Icon属性处,为按钮选择一个图标,并将其IconAlignment 属性设置为top(将图标放在上方)。并将其Position 属性设置为 [16 23 60 60],即大小为60×60。效果如下。

右键点击图标,添加回调函数 Button_newprohjectPushed。回调函数位于methods (Access = private)下。目前函数内没有任何代码。

methods (Access = private)
% Button pushed function: Button_newprohject
function Button_newprohjectPushed(app, event)
end
end
点击上方的编辑器控制页面,选择属性下方的下拉箭头,选择私有属性。系统会生成一个 properties (Access = private)...end区域,这个区域用于存放我们的app_01的属性(即对象)。在下面新建一个属性(对象)projects_info并将其初始化为空数组。
matlab中使用%来注释,注释后的文字不作为代码,是对代码的说明,便于后续阅读,建议大家多多注释。编辑器中的代码模块可以对代码进行注释,缩进管理。

properties (Access = private)
projects_info=[]; % 存储项目信息
end

在 Button_newprohjectPushed函数下增加以下代码。该回调函数是通过matlab的编程方式建立对话框和组件,一共包括三个部分,以下分开讲解。
第一部分
效果图和源代码如下:

selection = uiconfirm(app.UIFigure,"新建项目前请确认保存的现有的项目,是否开始新建项目?","确认新建项目","Icon","warning");
if isequal('Cancel',selection)
return
end
通过新建确认对话框向用户确认是否新建,该处设置是否新建的原因是后续使用过程中会有数据覆盖问题,所以要请用户确认。
使用了matlab的专用dlg(对话框)中的一种:uiconfirm(确认对话框)。函数的matlab帮助文件说明。较为常用的方式是
selection = uiconfirm(fig,message,title, "Icon","warning");
其中
selection 是用户选择的结果,返回值是字符串,默认是'OK'、'Cancel'。用户可以自定义。
fig 是目标图窗,即父对象。
message 是显示在对话框中的提示信息,是编程时给的,格式是char(字符)或者string(字符串。
title 对话框的标题,是编程时给的,格式是char(字符)或者string(字符串。
Icon 用于设置图标,可以设置也可以不设置,值是字符串表达的图片名称(系统自带),也可以自定义给文件地址。
if isequal('Cancel',selection)用于判断用户的选择,如果选择'Cancel'(取消)则直接返回(return),不执行后续代码。
isequal函数用于判断内部的对象是否一致。此处判断选择结果selection与'Cancel'是否一致,从而做出后续的判断。 见matlab帮助。
if 语句是matlab中常用判断语句,见matlab帮助。
第二部分
效果图和源代码如下:

%第二部分:通过模态对话框的方式建立新的新建对话框
d = dialog('Position',[500 400 500 250],'Name','新建项目');
%项目名称
name_label = uicontrol('Parent',d,...
'Style','text',...
'Position',[30 210 100 20],...
'String','项目名称');
name_txt=uicontrol('Parent',d,...
'Style','edit',...
'Position',[120 210 300 20],...
HorizontalAlignment='left');
%项目说明
info_label = uicontrol('Parent',d,...
'Style','text',...
'Position',[30 150 100 20],...
'String','项目说明');
info_txt=uicontrol('Parent',d,...
'Style','edit',...
'Position',[120 130 300 60],...
'Min',0,'Max',1000,...
'String','',...
HorizontalAlignment='left');
%保存地址
foldernow=pwd;%获取当前文件地址
folder_label = uicontrol('Parent',d,...
'Style','text',...
'Position',[30 100 100 20],...
'String','项目地址');
folder_txt=uicontrol('Parent',d,...
'Style','edit',...
'Position',[120 100 300 20],...
'String',foldernow,...
HorizontalAlignment='left');
button_folder = uicontrol('Parent',d,...
'Position',[420 97 50 25],...
'String','选择',...
Callback=@button_folder_Pushed);
%确定按钮
button_done = uicontrol('Parent',d,...
'Position',[350 20 70 25],...
'String','确定',...
Callback=@button_done_Pushed);
MATLAB中的模态对话框是一种特殊的交互窗口,具有以下核心特点和功能:
- 会阻止用户与其他MATLAB窗口交互,直到对话框关闭
- 强制保持焦点在当前窗口,形成操作阻断效果
- 典型应用包括关键操作确认、错误提示等场景
第二部分为以下几步
- 通过dialog创建对话框。
- 通过uicontrol创建text、edit、pushbutton等组件。
dialog是创建模态对话框的方式,其使用方式请查看帮助。比较重要的且常用的属性是Position和Name,用于约束位置和标题栏内容。如:
d = dialog('Position',[500 400 500 250],'Name','新建项目');
uicontrol用于定义模态对话框中的组件,定义的方式是属性名称和属性值作为一组出现,有两种属性的表达方式,如:
'Style','text', %用单引号括起来的属性及其取值
Style='text', %用等号表达的属性及其取值,两者的作用是一样的
常用的属性包括:
- Position,位置,值为数组,如 [500 400 500 250];
- Style,样式,即组件类型,有:'pushbutton'、'togglebutton'、'checkbox'、'radiobutton'、'edit'、'text'、'slider'、'listbox'、'popupmenu';
- Value ,值,可以用于设置默认值,也可以用于获取用户值;
- String,控件显示的文字名称;
- Callback回调函数;
- 其他属性请查看帮助。
Callback=@button_folder_Pushed的作用是,定义当前pushbutton的回调函数,目前用的内联回调函数,函数button_folder_Pushed只能在上级回调函数Button_newprohjectPushed内部调用,且不用app.的前缀,输入参数也不用app。
如果将button_folder_Pushed设置为app_01的函数,则调用时要改为Callback=@app.button_folder_Pushed,相应的button_folder_Pushed应该放置到methods (Access = private)或者methods (Access = public)下面,button_folder_Pushed的输入值需要添加app,即button_folder_Pushed(app,src,event),如果此时button_folder_Pushed没有调用app的任何信息,可以省略为button_folder_Pushed(~,src,event),其中的~不可省略,否则系统识别错误。
第三部分
包括两个回调函数,button_folder_Pushed和button_done_Pushed,分别响应用户点击按钮button_folder(选择文件夹)和button_done(完成)
回调函数button_folder_Pushed
function button_folder_Pushed(src,event)%按钮选择btn_folder(选择)的回调函数
foldernow=pwd;%获取当前文件地址
try
newdir=uigetdir(foldernow,'选择文件夹');
folder_txt.String=newdir;
catch ME
errordlg(sprintf('失败 %s',ME.message));
end
end
两个输入参数,src和event
src表示触发回调事件的源对象,通常是用户交互的UI控件(如按钮、滑块等)或图形对象(如坐标轴、线条等)。例如点击按钮时,src会指向该按钮的实例对象。可通过src.PropertyName访问控件的所有属性(如String、Position、Color等),如
src.Text = 'Clicked'; % 修改按钮文本
event参数(全称eventdata)是记录事件触发时相关数据的对象,其内容根据不同的控件和事件类型而变化。event用于传递与事件相关的附加信息,例如:
- 鼠标点击的坐标位置
- 键盘按键的字符
- 滑块移动的数值变化量
- 表格单元格的修改内容
function sliderMoved(src, event)
event.Value % 滑块当前值
event.PreviousValue % 滑块之前的值
event.Source % 触发事件的控件对象(同src)
end
回调函数button_folder_Pushed,首先通过 pwd 函数获取当前文件夹,matlab中的当前文件夹指matlab主程序当前的文件夹,即主程序地址栏显示的地址,如:

然后通过try...catch...end语句处理后续代码, try...catch...end语句能够有效处理错误,代码运行时先执行try和catch之间的语句,发生错误后执行catch和end之间的语句。
在button_folder_Pushed回调中,try和catch之间的语句用于获取,用户选择的文件夹地址newdir,并将新的地址赋值给folder_txt的String属性,让用户能够看到自己选择的地址。
获取地址用到了函数uigetdir,用于打开一个对话框供用户选择文件夹,使用格式如下,selpath是用户选择的路径,path是我们设置的默认路径,也就是用户打开对话框是显示的路径,title是对话框的标题,path和title输入可以省略:
selpath = uigetdir%不设置默认地址和标题,此时的地址是matlab主程序当前的文件夹
selpath = uigetdir(path)%设置默认地址
selpath = uigetdir(path,title)%设置默认地址和标题
如果try和catch之间的语句运行发生错误,则执行catch和end之间的语句。此处catch 后面有一个参数ME,用于获取错误的信息,ME(MException)的参数信息见帮助,我们常用的是message属性,用于返回错误信息的文字说明。
在catch和end之间,使用errordlg对话框处理错误信息。errordlg最核心的输入参数就是msg,即错误信息,是'字符向量'(char)或者"字符串"(string)。
回调函数button_done_Pushed
function button_done_Pushed(src,event)%按钮选择button_done(确定)的回调函数
name=name_txt.get('String');
info=info_txt.get('String');
projectdir=folder_txt.get('string');
if ~isempty(name)
timenow=datetime('now', 'Format', 'yyyy-MM-dd HH:mm:ss', 'TimeZone', 'local');
col1=name;
col2=char(timenow);
col3=char(timenow);
col4=projectdir;
col5=info;
row_data={col1,col2,col3,col4,col5};
%新建文件夹
try
newdir=char(sprintf('%s/%s',projectdir,name));
if ~exist(projectdir,'dir')
mkdir(projectdir);
end
mkdir(newdir);
%赋初值
app.project_name=name;%项目名称
app.project_dir=projectdir;%项目地址
app.create_time=col2;%创建时间
app.last_modefied_time=col3;%最后修改时间
app.projects_info=[app.projects_info;row_data];
app.UITable_projectlist.Data=app.projects_info;
app.save_projects_info;
delete(gcf);
catch ME
rmdir(newdir, 's');
errordlg(ME.message);
errordlg(sprintf('失败 %s',ME.message));
delete(gcf);
end
end
button_done_Pushed回调函数的第一部分是获取用户设置的项目名称(name)、项目介绍(info)、项目所在地址(projectdir),通过 .get('String')的方式分别获取name_txt、info_txt、folder_txt三个组件的值,得到的都是字符串。
name=name_txt.get('String');
info=info_txt.get('String');
projectdir=folder_txt.get('string');
然后通过~isempty(name)判断name是不是空数组,不是空数组的话就继续执行后续代码,即将获得的name、info、projectdir信息作为新的项目信息建立新项目,建立新项目包括以下几个部分
1、构建新项目信息
新项目信息包括前面提到的name、info、projectdir,为了便于识别项目,我们增加项目的创建时间和最后更新时间的信息,即col2,col3,通过datetime函数获取按格式的时间。
'now' 代表获取当前时间;
'Format', 'yyyy-MM-dd HH:mm:ss' 时间的格式定义为“年-月-日 小时-分钟-秒”
'TimeZone', 'local' 时区选择本地时间
由于datatime格式不能直接赋值给UITable所以这里直接转化为字符向量char,即char(timenow)。
将col1~col5通过大括号{}转化为元胞数组,元胞数组和普通数组的区别是可以容纳不同类型的元素,同时可以直接给表UITable赋值。
timenow=datetime('now', 'Format', 'yyyy-MM-dd HH:mm:ss', 'TimeZone', 'local');
col1=name;
col2=char(timenow);
col3=char(timenow);
col4=projectdir;
col5=info;
row_data={col1,col2,col3,col4,col5};
在开始后续代码前为app_01新建几个属性,如下:
properties (Access = private)
projects_info=[]; % 存储项目信息
project_name;%项目名称 ,新建的属性
project_dir;%项目地址 ,新建的属性
create_time;%创建时间 ,新建的属性
last_modefied_time;%最后修改时间 ,新建的属性
end
2、接下来使用try...catch...end处理后续代码
将前面获取的用户选择文件夹和文件名合并为新的文件地址newdir。
使用~exist(projectdir,'dir')判断用户选择的文件夹是否存在;
如果不存在则新建这个文件夹地址mkdir(projectdir);
然后建立项目所在文件夹地址mkdir(newdir);
此处使用了函数mkdir,其使用语法有以下几种:
mkdir newdir %当前目录下直接新建名为newdir的文件夹
[status, msg, msgID] = mkdir('newFolder')%在当前文件夹下创建newFolder的文件夹,返回值status为1标识成功,0表示失败,msg返回错误信息,msgID错误信息的ID,如status = logical 1,msg = 'Directory already exists.',msgID = 'MATLAB:MKDIR:DirectoryExists'
mkdir('newFolder','parentdir')%输入文件夹可以有两个参数,要建立的文件夹newFolder和父文件夹parentdir,也可以使用案例中的方式将newFolder设置为完整的文件夹路径
将新建的项目赋值给app_01,作为当前项目,调用app_01的所有属性和函数,都要在前面加上 app. 。这是matlab规定的app类调用的方法。
%赋初值
app.project_name=name;%项目名称
app.project_dir=projectdir;%项目地址
app.create_time=col2;%创建时间
app.last_modefied_time=col3;%最后修改时间
将新的项目信息添加到 app.projects_info的下一行
app.projects_info=[app.projects_info;row_data];
将projects_info赋值给UITable_projectlist显示给用户看。
app.UITable_projectlist.Data=app.projects_info;
try
newdir=char(sprintf('%s/%s',projectdir,name));
if ~exist(projectdir,'dir')
mkdir(projectdir);
end
mkdir(newdir);
%赋初值
app.project_name=name;%项目名称
app.project_dir=projectdir;%项目地址
app.create_time=col2;%创建时间
app.last_modefied_time=col3;%最后修改时间
app.projects_info=[app.projects_info;row_data];
app.UITable_projectlist.Data=app.projects_info;
app.save_projects_info;
delete(gcf);
catch ME
rmdir(newdir, 's');
errordlg(ME.message);
errordlg(sprintf('失败 %s',ME.message));
delete(gcf);
end
delete(gcf)用于删除当前对话框,更准确的方式是delete(d),删除我们建立的对话框d。
如果过程出现了问题,则删除新建的文件夹。
最后给app_01新建一个函数save_projects_info,用于保存projects_info;
save函数,的输入参数包括保存的文件名、要保存的对象名(可以是多个对象),不设置地址默认保存在当前文件夹。
methods (Access = private)
function save_projects_info(app)%将projects info保存到本地
projects_info=app.projects_info;
save("projects_info.mat","projects_info");
end
end
同时,为了在项目起动时就能够显示我们保存的项目,需要为app_01添加回调函数startupFcn(app), 这是系统自带的回调函数。在组件浏览器中选择app_01,点击编辑器的回调,然后选择startupFcn


新建并添加以下代码:首先判断projects_info.mat文件是否存在,如果存在则加载(load),并将数据赋值给app.projects_info;在赋值给UITable_projectlist。
function startupFcn(app)
%导入项目清单
try
folder=pwd;
fulefilename=fullfile(folder, 'projects_info.mat');
if exist(fulefilename,"file")
projectsinfo=load("projects_info.mat");
app.projects_info=projectsinfo.projects_info;
app.UITable_projectlist.Data=app.projects_info;
end
catch ME
errordlg(sprintf('错误 %s',ME.message));
end
end
本章完整代码如下
function Button_newprohjectPushed(app, event)
%第一部分:提示是否新建项目
selection = uiconfirm(app.UIFigure,"新建项目前请确认保存的现有的项目,是否开始新建项目?","确认新建项目", ...
"Icon","warning");
if isequal('Cancel',selection)
return
end
%第二部分:通过编程代码的方式建立新的新建对话框
d = dialog('Position',[500 400 500 250],'Name','新建项目');
%项目名称
name_label = uicontrol('Parent',d,...
'Style','text',...
'Position',[30 210 100 20],...
'String','项目名称');
name_txt=uicontrol('Parent',d,...
'Style','edit',...
'Position',[120 210 300 20],...
HorizontalAlignment='left');
%项目说明
info_label = uicontrol('Parent',d,...
'Style','text',...
'Position',[30 150 100 20],...
'String','项目说明');
info_txt=uicontrol('Parent',d,...
'Style','edit',...
'Position',[120 130 300 60],...
'Min',0,'Max',1000,...
'String','',...
HorizontalAlignment='left');
%保存地址
foldernow=pwd;%获取当前文件地址
folder_label = uicontrol('Parent',d,...
'Style','text',...
'Position',[30 100 100 20],...
'String','项目地址');
folder_txt=uicontrol('Parent',d,...
'Style','edit',...
'Position',[120 100 300 20],...
'String',foldernow,...
HorizontalAlignment='left');
button_folder = uicontrol('Parent',d,...
'Style','pushbutton',...
'Position',[420 97 50 25],...
'String','选择',...
Callback=@button_folder_Pushed);
%确定按钮
button_done = uicontrol('Parent',d,...
'Style','pushbutton',...
'Position',[350 20 70 25],...
'String','确定',...
Callback=@button_done_Pushed);
%第三部分:新建对话框中回调函数
function button_folder_Pushed(src,event)%按钮选择btn_folder(选择)的回调函数
foldernow=pwd;%获取当前文件地址
try
newdir=uigetdir(foldernow,'选择文件夹');
folder_txt.String=newdir;
catch ME
errordlg(sprintf('失败 %s',ME.message));
end
end
function button_done_Pushed(src,event)%按钮选择button_done(确定)的回调函数
name=name_txt.get('String');
info=info_txt.get('String');
projectdir=folder_txt.get('string');
if ~isempty(name)
timenow=datetime('now', 'Format', 'yyyy-MM-dd HH:mm:ss', 'TimeZone', 'local');
col1=name;
col2=char(timenow);
col3=char(timenow);
col4=projectdir;
col5=info;
row_data={col1,col2,col3,col4,col5};
%新建文件夹
try
newdir=char(sprintf('%s/%s',projectdir,name));
if ~exist(projectdir,'dir')
mkdir(projectdir);
end
mkdir(newdir);
%赋初值
app.project_name=name;%项目名称
app.project_dir=projectdir;%项目地址
app.create_time=col2;%创建时间
app.last_modefied_time=col3;%最后修改时间
app.projects_info=[app.projects_info;row_data];
app.UITable_projectlist.Data=app.projects_info;
app.save_projects_info;
delete(gcf);
catch ME
rmdir(newdir, 's');
errordlg(ME.message);
errordlg(sprintf('失败 %s',ME.message));
delete(gcf);
end
end
end
end
「智能机器人开发者大赛」官方平台,致力于为开发者和参赛选手提供赛事技术指导、行业标准解读及团队实战案例解析;聚焦智能机器人开发全栈技术闭环,助力开发者攻克技术瓶颈,促进软硬件集成、场景应用及商业化落地的深度研讨。 加入智能机器人开发者社区iRobot Developer,与全球极客并肩突破技术边界,定义机器人开发的未来范式!
更多推荐
所有评论(0)