第二篇matlab app 学习笔记:新建选项卡组TabGroup、面板Panel、按钮Button、表UITable
一、添加UITable表删除操作
在app.Tab_datamanage页面,在app.panel_datamanage面板内新增一个面板app.panel_datamanage2,在面板内增加三个按钮“删除行”(app.btn_deleterow_data)、“删除列”(app.btn_deletecol_data)、“清空”(app.btn_deleteall_data)。

(一)增加“删除行”(app.btn_deleterow_data)的回调函数
回调函数的思路是先获取用户选择selects=app.UITable_data.Selection,再筛选出选择的行uniquerows=unique(rows),最后将这些行的值设置为空app.UITable_data.Data(uniquerows,:)=[];同时将行名的对应部分也清空(如有)app.UITable_data.RowName(uniquerows)=[];。
function btn_deleterow_dataButtonPushed(app, event)
try
selects=app.UITable_data.Selection;%获取用户选择的单元格列表(二维数组,选择模式是cell)
if ~isempty(selects)
rows=selects(:,1);%获得行数组
uniquerows=unique(rows);%去除重复项
app.UITable_data.Data(uniquerows,:)=[];%将选择的行的数据清空,即删除行
if ~isempty(app.UITable_data.RowName)
app.UITable_data.RowName(uniquerows)=[];%删除对应的行名(如有)
end
end
catch ME
errordlg(ME.message);%如果发生错误,弹出错误提示框
end
end
(二)增加“删除列”(app.btn_deletecol_data)的回调函数
回调函数的思路与上面的删除行一致。代码如下:
function btn_deletecol_dataButtonPushed(app, event)
try
selects=app.UITable_data.Selection;
if isempty(selects)
return;
end
selectedColumns = selects(:,2);%获取列数组
uniqueColumns = unique(selectedColumns)';%去重并排序
app.UITable_data.Data(:,uniqueColumns)=[];%删除列
if ~isempty(app.UITable_data.ColumnName)
app.UITable_data.ColumnName(uniqueColumns)=[];%删除列名
end
catch ME
errordlg(ME.message);
end
end
(三)增加“清空”(app.btn_deleteall_data)的回调函数
代码如下:
function btn_deleteall_dataButtonPushed(app, event)
app.UITable_data.Data=[];
end
二、添加UITable列查找操作
当UITable中的列很多时,要查找某个参数的数据会比较困难,因此增加按列名查找的功能。
在app.panel_datamanage面板内新增一个面板app.panel_datamanage3,在面板内增加编辑字段(文本)(查找输入框)app.editfield_findcol_data,和按钮“查找”app.btn_findcol_data。

回调函数有两个:
- 编辑字段(文本)(查找输入框)app.editfield_findcol_data的ValueChanged回调,当用户输入完成点击回车时生效;
- “查找”app.btn_findcol_data的回调函数,用户点击时生效,该回调直接调用编辑字段的回调即可。
代码如下:
function editfield_findcol_dataValueChanged(app, event)
%通过lower将用户输入的字符和列名转化为小写,在列名中查找用户输入的列名,并将表的选择置于列的第一个cell
find_value = lower(app.editfield_findcol_data.Value);%获取用户输入并转化为小写
cols=lower(app.UITable_data.ColumnName);%获取表列名并转化为小写
try
col = find(contains(cols, find_value));%查找列名所在的位置,contains返回大小与cols相同的逻辑数组,find找的其中为true的值的位置
scroll(app.UITable_data, 'column', col);%将UITable按列滚动到查找到的列处
app.UITable_data.Selection=[1,col];%将UITable的选择设置为查到到的列的第一个cell
catch ME
errordlg(ME.message);
end
end
function btn_findcol_dataButtonPushed(app, event)
app.editfield_findcol_dataValueChanged;%调用现有回调函数
end
三、添加单元格内容显示控件
由于UITable控件默认显示小数位数为4位,本可以通过format设置显示格式,但大量数据显示全部小数位数并不利于数据处理,我们往往只是需要查看特定单元的实际数值,就可以通过添加一个编辑字段控件来显示用户选择的table表格中cell对应的数据。
在app.panel_datamanage面板内新增一个面板app.panel_datamanage4,在面板内增加编辑字段(数值)app.editfield_findcol_data,和按钮“查找”app.editfield_selectedcell_data。

这里添加的回调函数是UITable的回调,即当用户选择发生变化后的回调。代码如下:
function UITable_dataSelectionChanged(app, event)
selection = app.UITable_data.Selection;%获取用户选择的单元格
last_cell=selection(end,:);%选择最后一个单元格
app.editfield_selectedcell_data.Value= table2array(app.UITable_data.Data(last_cell(1),last_cell(2)));%将单元格的信息显示在editfield上
end
四、添加撤销操作
当我们编辑表格等内容时,往往存在错误操作需要返回上一步的情况,这时候撤销操作显得尤为重要,二小操作的步骤如下:
1.将用户的操作即数据记录下来
涉及UITable的操作,在本页面有:删除行、删除列、清空、编辑单元格。我们为每一个操作增加一个记录更改前数据和更改后数据的记录,并记录在程序的属性logOperation。
在app中增加三个参数:
MaxUndoLevels = 5; % 最大撤销步数
LogBuffer = {}; % 操作日志记录
CurrentIndex = 0 ; % 当前操作位置
删除行在原按钮的回调函数中增加代码后如下:
function btn_deleterow_dataButtonPushed(app, event)
%前三行为增加代码,记录更改前的表数据
preData=app.UITable_data.Data;
preData.Properties.VariableNames=app.UITable_data.ColumnName;%存储列名
preData.Properties.RowNames=app.UITable_data.RowName;%存储行名
try
selects=app.UITable_data.Selection;%获取用户选择的单元格列表(二维数组,选择模式是cell)
if ~isempty(selects)
rows=selects(:,1);%获得行数组
uniquerows=unique(rows);%去除重复项
app.UITable_data.Data(uniquerows,:)=[];%将选择的行的数据清空,即删除行
if ~isempty(app.UITable_data.RowName)
app.UITable_data.RowName(uniquerows)=[];%删除对应的行名(如有)
end
end
%后面三行增加的代码记录修改后的数据
newData=app.UITable_data.Data;
newData.Properties.VariableNames=app.UITable_data.ColumnName;%存储列名
newData.Properties.RowNames=app.UITable_data.RowName;%存储行名
%接下来通过logOperation函数记录变更类型、变更对象、原数据,新数据到LogBuffer
app.logOperation('tableEdit','UITable_data',preData,newData);
%由于用于有了新的操作,将记录操作步骤置为当前
app.CurrentIndex=height(app.LogBuffer);
catch ME
errordlg(ME.message);%如果发生错误,弹出错误提示框
end
end
删除列在原按钮的回调函数中增加代码后如下:
% Button pushed function: btn_deletecol_data
function btn_deletecol_dataButtonPushed(app, event)
preData=app.UITable_data.Data;
preData.Properties.VariableNames=app.UITable_data.ColumnName;%存储列名
preData.Properties.RowNames=app.UITable_data.RowName;%存储行名
try
selects=app.UITable_data.Selection;
if isempty(selects)
return;
end
selectedColumns = selects(:,2);%获取列数组
uniqueColumns = unique(selectedColumns)';%去重并排序
app.UITable_data.Data(:,uniqueColumns)=[];%删除列
if ~isempty(app.UITable_data.ColumnName)
app.UITable_data.ColumnName(uniqueColumns)=[];%删除列名
end
newData=app.UITable_data.Data;
newData.Properties.VariableNames=app.UITable_data.ColumnName;%存储列名
newData.Properties.RowNames=app.UITable_data.RowName;%存储行名
app.logOperation('tableEdit','UITable_data',preData,newData);
app.CurrentIndex=height(app.LogBuffer);
catch ME
errordlg(ME.message);
end
end
清空在原按钮的回调函数中增加代码后如下:
function btn_deleteall_dataButtonPushed(app, event)
preData=app.UITable_data.Data;
preData.Properties.VariableNames=app.UITable_data.ColumnName;%存储列名
preData.Properties.RowNames=app.UITable_data.RowName;%存储行名
app.UITable_data.Data=[];
newData=app.UITable_data.Data;
newData.Properties.VariableNames=[];%存储列名
newData.Properties.RowNames=[];
app.logOperation('tableEdit','UITable_data',preData,newData);
app.CurrentIndex=height(app.LogBuffer);
end
编辑单元格的回调时UITable的回调函数,代码如下:
% Cell edit callback: UITable_data
function UITable_dataCellEdit(app, event)
indices = event.Indices;%编辑单元格的行列数组,如[1,2]为第1行第2列
preData=event.PreviousData;%修改前的单元格数据
preData.Properties.VariableNames=app.UITable_data.ColumnName;%存储列名
preData.Properties.RowNames=app.UITable_data.RowName;%存储行名
pretabledata=app.UITable_data.Data;%当前表数据赋值给修改前的数据存储
pretabledata(indices(1),indices(2))=table(preData);%将修改前的数据存储中已经修改过的数据改回原来的值
newData = app.UITable_data.Data;%保存新的数据
newData.Properties.VariableNames=app.UITable_data.ColumnName;%存储列名
newData.Properties.RowNames=app.UITable_data.RowName;%存储行名
app.logOperation('tableEdit','UITable_data',pretabledata,newData);%存储修改类型、控件名称、原数据、新数据到LogBuffer
app.CurrentIndex=height(app.LogBuffer);
end
logOperation函数如下:
function logOperation(app, actionType, targetId,preData,newData)
app.LogBuffer = [app.LogBuffer; {datetime('now'), actionType, targetId, preData,newData}];%在LogBuffer 下一行增加新的操作数据
app.CurrentIndex = height(app.LogBuffer);%因为人为修改了数据,将操作顺序的记录置为当前
if height(app.LogBuffer) > app.MaxUndoLevels%如果LogBuffer 数量超过了预定的长度(允许撤销的次数),将第一个操作置空删除
app.LogBuffer(1,:) = [];
end
end
2.建立工具栏和撤销、重做按钮
在UIFigure下新家一个工具栏toolbar,并添加按钮工具app.PushTool_undo和app.PushTool_redo。
PushTool_undo用于撤销操作,PushTool_redo用于重做操作。

对PushTool_undo添加回调函数:
% Callback function: PushTool_undo
function PushTool_undoClicked(app, event)
if app.CurrentIndex > 0
app.undoAction(app.CurrentIndex);%调用undo函数
if app.CurrentIndex>1
app.CurrentIndex = app.CurrentIndex - 1;%将序号调整到前一步操作
end
end
end
function undoAction(app,index)
if index>=1&&index<=height(app.LogBuffer)
op = app.LogBuffer(index, :);%获取当前操作序号的记录
switch op{2}
case 'tableEdit'%判断修改类型,如果为tableEdit,表编辑,我自定义的
app.(op{3}).Data = op{4};%将存在的原数据加载到表app.(op{3})是通过控件名称调用控件的方式即app.('UITable_data')
app.(op{3}).ColumnName=op{4}.Properties.VariableNames;%将原列名赋值给UITable
app.(op{3}).RowName=op{4}.Properties.RowNames;%将原行名赋值给UITable
case 'textInput'
app.(op{3}).Value = op{4};
% 可扩展其他控件类型
end
end
end
对PushTool_redo添加回调函数:
% Callback function: PushTool_redo
function PushTool_redoClicked(app, event)
if app.CurrentIndex > 0
app.redoAction(app.CurrentIndex);
if app.CurrentIndex<height(app.LogBuffer)
app.CurrentIndex = app.CurrentIndex + 1;
end
end
end
function redoAction(app,index)
if index>=1&&index<=height(app.LogBuffer)
op = app.LogBuffer(index, :);
switch op{2}
case 'tableEdit'
app.(op{3}).Data = op{5};%将新数据重新赋值给UITable
app.(op{3}).ColumnName=op{5}.Properties.VariableNames;
app.(op{3}).RowName=op{5}.Properties.RowNames;
case 'textInput'
app.(op{3}).Value = op{5};
% 可扩展其他控件类型
end
end
end
五、完整代码
classdef app_01 < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
Toolbar matlab.ui.container.Toolbar
PushTool_undo matlab.ui.container.toolbar.PushTool
PushTool_redo matlab.ui.container.toolbar.PushTool
TabGroup matlab.ui.container.TabGroup
Tab_projects matlab.ui.container.Tab
EditField_loadedproject matlab.ui.control.EditField
EditFieldLabel matlab.ui.control.Label
Panel_projects matlab.ui.container.Panel
Button_saveproject matlab.ui.control.Button
Button_loadproject matlab.ui.control.Button
Button_deleteproject_fromlist matlab.ui.control.Button
Button_deleteproject matlab.ui.control.Button
Button_newprohject matlab.ui.control.Button
UITable_projectlist matlab.ui.control.Table
Tab_datamanage matlab.ui.container.Tab
UITable_data matlab.ui.control.Table
panel_datamanage matlab.ui.container.Panel
panel_datamanage1 matlab.ui.container.Panel
Button_savedata matlab.ui.control.Button
Button_loaddata matlab.ui.control.Button
Button_importdatafromexcel matlab.ui.control.Button
Button_outputdatatoexcel matlab.ui.control.Button
panel_datamanage2 matlab.ui.container.Panel
btn_deleterow_data matlab.ui.control.Button
btn_deletecol_data matlab.ui.control.Button
btn_deleteall_data matlab.ui.control.Button
panel_datamanage3 matlab.ui.container.Panel
editfield_findcol_data matlab.ui.control.EditField
Label matlab.ui.control.Label
btn_findcol_data matlab.ui.control.Button
panel_datamanage4 matlab.ui.container.Panel
editfield_selectedcell_data matlab.ui.control.NumericEditField
Label_2 matlab.ui.control.Label
end
properties (Access = private)
projects_info=[]; % 存储项目信息
project_name;%项目名称
project_dir;%项目地址
create_time;%创建时间
last_modefied_time;%最后修改时间
data=[];%存储主数据
MaxUndoLevels = 5; % 最大撤销步数
LogBuffer = {}; % 操作日志
CurrentIndex = 0 ; % 当前操作位置
end
methods (Access = private)
function save_projects_info(app)%将projects info保存到本地
projects_info=app.projects_info;
save("projects_info.mat","projects_info");
end
function logOperation(app, actionType, targetId,preData,newData)
app.LogBuffer = [app.LogBuffer; {datetime('now'), actionType, targetId, preData,newData}];
app.CurrentIndex = height(app.LogBuffer);
if height(app.LogBuffer) > app.MaxUndoLevels
app.LogBuffer(1,:) = [];
end
end
function undoAction(app,index)
if index>=1&&index<=height(app.LogBuffer)
op = app.LogBuffer(index, :);
switch op{2}
case 'tableEdit'
app.(op{3}).Data = op{4};
app.(op{3}).ColumnName=op{4}.Properties.VariableNames;%存储列名
app.(op{3}).RowName=op{4}.Properties.RowNames;%存储行名
case 'textInput'
app.(op{3}).Value = op{4};
% 可扩展其他控件类型
end
end
end
function redoAction(app,index)
if index>=1&&index<=height(app.LogBuffer)
op = app.LogBuffer(index, :);
switch op{2}
case 'tableEdit'
app.(op{3}).Data = op{5};
app.(op{3}).ColumnName=op{5}.Properties.VariableNames;%存储列名
app.(op{3}).RowName=op{5}.Properties.RowNames;%存储行名
case 'textInput'
app.(op{3}).Value = op{5};
% 可扩展其他控件类型
end
end
end
end
% Callbacks that handle component events
methods (Access = private)
% Code that executes after component creation
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
% Cell edit callback: UITable_data
function UITable_dataCellEdit(app, event)
indices = event.Indices;
preData=event.PreviousData;
preData.Properties.VariableNames=app.UITable_data.ColumnName;%存储列名
preData.Properties.RowNames=app.UITable_data.RowName;%存储行名
pretabledata=app.UITable_data.Data;
pretabledata(indices(1),indices(2))=table(preData);
newData = app.UITable_data.Data;
newData.Properties.VariableNames=app.UITable_data.ColumnName;%存储列名
newData.Properties.RowNames=app.UITable_data.RowName;%存储行名
app.logOperation('tableEdit','UITable_data',pretabledata,newData);
app.CurrentIndex=height(app.LogBuffer);
end
% Callback function: PushTool_undo
function PushTool_undoClicked(app, event)
if app.CurrentIndex > 0
app.undoAction(app.CurrentIndex);
if app.CurrentIndex>1
app.CurrentIndex = app.CurrentIndex - 1;
end
end
end
% Callback function: PushTool_redo
function PushTool_redoClicked(app, event)
if app.CurrentIndex > 0
app.redoAction(app.CurrentIndex);
if app.CurrentIndex<height(app.LogBuffer)
app.CurrentIndex = app.CurrentIndex + 1;
end
end
end
% Button pushed function: Button_newprohject
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.data=[];
app.projects_info=[app.projects_info;row_data];
app.UITable_projectlist.Data=app.projects_info;
app.EditField_loadedproject.Value=name;
app.save_projects_info;
app.Button_saveprojectPushed;
delete(d);
catch ME
rmdir(newdir, 's');
errordlg(ME.message);
errordlg(sprintf('失败 %s',ME.message));
delete(d);
end
end
end
end
% Button pushed function: Button_deleteproject_fromlist
function Button_deleteproject_fromlistPushed(app, event)
selects=app.UITable_projectlist.Selection;
rows=selects(1,:);
try
app.projects_info(rows,:)=[];
app.UITable_projectlist.Data=app.projects_info;
app.save_projects_info;
catch ME
errordlg(ME.message);
end
end
% Button pushed function: Button_deleteproject
function Button_deleteprojectPushed(app, event)
selection = uiconfirm(app.UIFigure,"选择“确定”后该项目的所有本地文件都将删除,是否仍要删除?","确认删除", ...
"Icon","warning");
if isequal('Cancel',selection)
return;
end
selects=app.UITable_projectlist.Selection;
rows=selects(:,1);
rows=unique(rows);
for i=height(rows):-1:1
try
row=rows(i,1);
name=cell2mat(app.projects_info(row,1));
projectdir=cell2mat(app.projects_info(row,4));
deldir=fullfile(projectdir,name);
rmdir(deldir, 's');
app.projects_info(row,:)=[];
catch ME
errordlg(ME.message);
end
end
app.UITable_projectlist.Data=app.projects_info;
app.save_projects_info;
end
% Button pushed function: Button_savedata
function Button_savedataButtonPushed(app, event)
try
if ~isempty(app.UITable_data.Data)
app.data=app.UITable_data.Data;%存储数据
app.data.Properties.VariableNames=app.UITable_data.ColumnName;%存储列名
app.data.Properties.RowNames=app.UITable_data.RowName;%存储行名
end
catch ME
errordlg(ME.message);
end
end
% Button pushed function: Button_loaddata
function Button_loaddataButtonPushed(app, event)
try
app.UITable_data.Data=app.data;%显示数据
app.UITable_data.ColumnName=app.data.Properties.VariableNames;%显示列名
app.UITable_data.RowName=app.data.Properties.RowNames;%显示行名
catch ME
errordlg(ME.message);
end
end
% Button pushed function: Button_importdatafromexcel
function Button_importdatafromexcelButtonPushed(app, event)
try
[file, location] = uigetfile({'*.xlsx','*.csv'}, '选择要导入的Excel文件');
fullfilename = fullfile(location, file);
sheets=sheetnames(fullfilename);
%导入选项
d = dialog('Position',[500 500 500 120],'Name','导入设置');
sheet_label = uicontrol('Parent',d,...
'Style','text',...
'Position',[30 60 100 40],...
'String','选择Sheet');
sheet_list=uicontrol('Parent',d,...
'Style','popupmenu',...
'String',sheets,...
'Position',[120 65 200 40]);
check_row=uicontrol('Parent',d,...
'Style','checkbox',...
'String','读取首列为行名称',...
'Value',1,...
'Position',[340 75 150 40]);
%确定按钮
btn_done = uicontrol('Parent',d,...
'Position',[340 40 70 25],...
'String','确定',...
Callback=@btn_done_Pushed);
catch ME
errordlg(ME.message);
end
function btn_done_Pushed(src,event)
try
%读取数据
sheet_value=sheet_list.get('Value');
sheet_str=sheets(sheet_value);
read_row_name=check_row.get('Value');
readdata = readtable(fullfilename,"Sheet",sheet_str,ReadRowNames=read_row_name,VariableNamingRule="preserve");
app.UITable_data.Data=readdata;
app.UITable_data.RowName=readdata.Properties.RowNames;
app.UITable_data.ColumnName=readdata.Properties.VariableNames;
app.data=readdata;
delete(gcf);
catch ME
errordlg(ME.message);
delete(gcf);
end
end
end
% Button pushed function: Button_outputdatatoexcel
function Button_outputdatatoexcelButtonPushed(app, event)
try
app.data=app.UITable_data.Data;%试验数据
app.data.Properties.VariableNames=app.UITable_data.ColumnName;
app.data.Properties.RowNames=app.UITable_data.RowName;
try
[file,location,~] = uiputfile('*.xlsx','选择文件夹','data_out');
filename=fullfile(location,file);
writetable(app.data,filename,"WriteVariableNames",true);
catch ME
errordlg(ME.message);
end
catch ME
errordlg(ME.message);
end
end
% Selection change function: TabGroup
function TabGroupSelectionChanged(app, event)
%判断是否加载了项目,如果没有,则返回到项目管理页面
selectedTab = app.TabGroup.SelectedTab;
if isempty(app.EditField_loadedproject.Value)
if ~isequal(selectedTab,app.Tab_projects)
app.TabGroup.SelectedTab=app.Tab_projects;
warndlg('请先加载项目或新建项目。');
end
end
end
% Button pushed function: Button_loadproject
function Button_loadprojectPushed(app, event)
selects=app.UITable_projectlist.Selection;
[m,~]=size(selects);
if m==1
try
row=selects(1);
name=cell2mat(app.UITable_projectlist.Data(row,1));
projectdir=cell2mat(app.UITable_projectlist.Data(row,4));
filename=fullfile(projectdir,name,'data.mat');
data=load(filename);
app.project_name=data.project_name;%项目名称
app.project_dir=data.project_dir;%项目地址
app.create_time=data.create_time;%创建时间
app.last_modefied_time=data.last_modefied_time;%最后修改时间
app.data=data.data;%试验数据
%显示数据
app.EditField_loadedproject.Value=app.project_name;%为加载项目
app.UITable_data.Data=app.data;%显示试验数据
app.UITable_data.ColumnName=app.data.Properties.VariableNames;%显示列名
app.UITable_data.RowName=app.data.Properties.RowNames;%显示行名
catch ME
errordlg(ME.message);
end
end
end
% Button pushed function: Button_saveproject
function Button_saveprojectPushed(app, event)
app.Button_savedataButtonPushed;
project_name=app.project_name;%项目名称
project_dir=app.project_dir;%项目保存地址
create_time=app.create_time;%创建时间
last_modefied_time=app.last_modefied_time;%最后修改时间
data=app.data;%试验数据
app.last_modefied_time=char(datetime('now', 'Format', 'yyyy-MM-dd HH:mm:ss', 'TimeZone', 'local'));
try
filename=fullfile(project_dir,project_name,'data.mat');
save(filename,"project_name","project_dir","create_time","last_modefied_time","data");
project_names=app.projects_info(:,1);
row=find(contains(project_names,project_name));
app.projects_info(row,3)={app.last_modefied_time};
app.UITable_projectlist.Data=app.projects_info;
catch ME
errordlg(ME.message);
end
end
% Button pushed function: btn_deleterow_data
function btn_deleterow_dataButtonPushed(app, event)
preData=app.UITable_data.Data;
preData.Properties.VariableNames=app.UITable_data.ColumnName;%存储列名
preData.Properties.RowNames=app.UITable_data.RowName;%存储行名
try
selects=app.UITable_data.Selection;%获取用户选择的单元格列表(二维数组,选择模式是cell)
if ~isempty(selects)
rows=selects(:,1);%获得行数组
uniquerows=unique(rows);%去除重复项
app.UITable_data.Data(uniquerows,:)=[];%将选择的行的数据清空,即删除行
if ~isempty(app.UITable_data.RowName)
app.UITable_data.RowName(uniquerows)=[];%删除对应的行名(如有)
end
end
newData=app.UITable_data.Data;
newData.Properties.VariableNames=app.UITable_data.ColumnName;%存储列名
newData.Properties.RowNames=app.UITable_data.RowName;%存储行名
app.logOperation('tableEdit','UITable_data',preData,newData);
app.CurrentIndex=height(app.LogBuffer);
catch ME
errordlg(ME.message);%如果发生错误,弹出错误提示框
end
end
% Button pushed function: btn_deletecol_data
function btn_deletecol_dataButtonPushed(app, event)
preData=app.UITable_data.Data;
preData.Properties.VariableNames=app.UITable_data.ColumnName;%存储列名
preData.Properties.RowNames=app.UITable_data.RowName;%存储行名
try
selects=app.UITable_data.Selection;
if isempty(selects)
return;
end
selectedColumns = selects(:,2);%获取列数组
uniqueColumns = unique(selectedColumns)';%去重并排序
app.UITable_data.Data(:,uniqueColumns)=[];%删除列
if ~isempty(app.UITable_data.ColumnName)
app.UITable_data.ColumnName(uniqueColumns)=[];%删除列名
end
newData=app.UITable_data.Data;
newData.Properties.VariableNames=app.UITable_data.ColumnName;%存储列名
newData.Properties.RowNames=app.UITable_data.RowName;%存储行名
app.logOperation('tableEdit','UITable_data',preData,newData);
app.CurrentIndex=height(app.LogBuffer);
catch ME
errordlg(ME.message);
end
end
% Button pushed function: btn_deleteall_data
function btn_deleteall_dataButtonPushed(app, event)
preData=app.UITable_data.Data;
preData.Properties.VariableNames=app.UITable_data.ColumnName;%存储列名
preData.Properties.RowNames=app.UITable_data.RowName;%存储行名
app.UITable_data.Data=[];
newData=app.UITable_data.Data;
newData.Properties.VariableNames=[];%存储列名
newData.Properties.RowNames=[];
app.logOperation('tableEdit','UITable_data',preData,newData);
app.CurrentIndex=height(app.LogBuffer);
end
% Value changed function: editfield_findcol_data
function editfield_findcol_dataValueChanged(app, event)
%通过lower将用户输入的字符和列名转化为小写,在列名中查找用户输入的列名,并将表的选择置于列的第一个cell
find_value = lower(app.editfield_findcol_data.Value);%获取用户输入并转化为小写
cols=lower(app.UITable_data.ColumnName);%获取表列名并转化为小写
try
col = find(contains(cols, find_value));%查找列名所在的位置,contains返回大小与cols相同的逻辑数组,find找的其中为true的值的位置
scroll(app.UITable_data, 'column', col);%将UITable按列滚动到查找到的列处
app.UITable_data.Selection=[1,col];%将UITable的选择设置为查到到的列的第一个cell
catch ME
errordlg(ME.message);
end
end
% Button pushed function: btn_findcol_data
function btn_findcol_dataButtonPushed(app, event)
app.editfield_findcol_dataValueChanged;%调用现有回调函数
end
% Selection changed function: UITable_data
function UITable_dataSelectionChanged(app, event)
selection = app.UITable_data.Selection;%获取用户选择的单元格
last_cell=selection(end,:);%选择最后一个单元格
app.editfield_selectedcell_data.Value= table2array(app.UITable_data.Data(last_cell(1),last_cell(2)));%将单元格的信息显示在editfield上
end
end
% Component initialization
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Get the file path for locating images
pathToMLAPP = fileparts(mfilename('fullpath'));
% Create UIFigure and hide until all components are created
app.UIFigure = uifigure('Visible', 'off');
app.UIFigure.Position = [10 60 1520 860];
app.UIFigure.Name = '第一个app';
app.UIFigure.Icon = fullfile(pathToMLAPP, 'icon01.png');
% Create Toolbar
app.Toolbar = uitoolbar(app.UIFigure);
% Create PushTool_undo
app.PushTool_undo = uipushtool(app.Toolbar);
app.PushTool_undo.ClickedCallback = createCallbackFcn(app, @PushTool_undoClicked, true);
app.PushTool_undo.Icon = fullfile(pathToMLAPP, 'ondo.png');
% Create PushTool_redo
app.PushTool_redo = uipushtool(app.Toolbar);
app.PushTool_redo.ClickedCallback = createCallbackFcn(app, @PushTool_redoClicked, true);
app.PushTool_redo.Icon = fullfile(pathToMLAPP, 'redo.png');
% Create TabGroup
app.TabGroup = uitabgroup(app.UIFigure);
app.TabGroup.SelectionChangedFcn = createCallbackFcn(app, @TabGroupSelectionChanged, true);
app.TabGroup.Position = [0 1 1520 859];
% Create Tab_projects
app.Tab_projects = uitab(app.TabGroup);
app.Tab_projects.Title = '项目管理';
% Create UITable_projectlist
app.UITable_projectlist = uitable(app.Tab_projects);
app.UITable_projectlist.ColumnName = {'项目名称'; '创建时间'; '最后修改时间'; '项目地址'; '项目说明'};
app.UITable_projectlist.RowName = {};
app.UITable_projectlist.Position = [17 20 1480 666];
% Create Panel_projects
app.Panel_projects = uipanel(app.Tab_projects);
app.Panel_projects.Position = [1 730 1520 105];
% Create Button_newprohject
app.Button_newprohject = uibutton(app.Panel_projects, 'push');
app.Button_newprohject.ButtonPushedFcn = createCallbackFcn(app, @Button_newprohjectPushed, true);
app.Button_newprohject.Icon = fullfile(pathToMLAPP, 'new.svg');
app.Button_newprohject.IconAlignment = 'top';
app.Button_newprohject.Position = [16 22 60 60];
app.Button_newprohject.Text = '新建项目';
% Create Button_deleteproject
app.Button_deleteproject = uibutton(app.Panel_projects, 'push');
app.Button_deleteproject.ButtonPushedFcn = createCallbackFcn(app, @Button_deleteprojectPushed, true);
app.Button_deleteproject.Icon = fullfile(pathToMLAPP, 'delete.svg');
app.Button_deleteproject.IconAlignment = 'top';
app.Button_deleteproject.FontColor = [1 0 0];
app.Button_deleteproject.Tooltip = {'注意:删除项目会删除所有项目文件。'};
app.Button_deleteproject.Position = [312 22 60 60];
app.Button_deleteproject.Text = '删除项目';
% Create Button_deleteproject_fromlist
app.Button_deleteproject_fromlist = uibutton(app.Panel_projects, 'push');
app.Button_deleteproject_fromlist.ButtonPushedFcn = createCallbackFcn(app, @Button_deleteproject_fromlistPushed, true);
app.Button_deleteproject_fromlist.Icon = fullfile(pathToMLAPP, 'delete_modifiedList.svg');
app.Button_deleteproject_fromlist.IconAlignment = 'top';
app.Button_deleteproject_fromlist.Tooltip = {'仅从列表中移除,不会删除数据文件及文件夹。'};
app.Button_deleteproject_fromlist.Position = [239 22 60 60];
app.Button_deleteproject_fromlist.Text = '剔除列表';
% Create Button_loadproject
app.Button_loadproject = uibutton(app.Panel_projects, 'push');
app.Button_loadproject.ButtonPushedFcn = createCallbackFcn(app, @Button_loadprojectPushed, true);
app.Button_loadproject.Icon = fullfile(pathToMLAPP, 'open_selectedWorkspace.svg');
app.Button_loadproject.IconAlignment = 'top';
app.Button_loadproject.Position = [163 22 63 60];
app.Button_loadproject.Text = '加载项目';
% Create Button_saveproject
app.Button_saveproject = uibutton(app.Panel_projects, 'push');
app.Button_saveproject.ButtonPushedFcn = createCallbackFcn(app, @Button_saveprojectPushed, true);
app.Button_saveproject.Icon = fullfile(pathToMLAPP, 'saved.svg');
app.Button_saveproject.IconAlignment = 'top';
app.Button_saveproject.Position = [89 22 63 60];
app.Button_saveproject.Text = '保存项目';
% Create EditFieldLabel
app.EditFieldLabel = uilabel(app.Tab_projects);
app.EditFieldLabel.HorizontalAlignment = 'right';
app.EditFieldLabel.Position = [17 697 89 22];
app.EditFieldLabel.Text = '已经加载的项目';
% Create EditField_loadedproject
app.EditField_loadedproject = uieditfield(app.Tab_projects, 'text');
app.EditField_loadedproject.Position = [121 697 487 22];
% Create Tab_datamanage
app.Tab_datamanage = uitab(app.TabGroup);
app.Tab_datamanage.Title = '数据管理';
% Create panel_datamanage
app.panel_datamanage = uipanel(app.Tab_datamanage);
app.panel_datamanage.Position = [1 730 1520 105];
% Create panel_datamanage4
app.panel_datamanage4 = uipanel(app.panel_datamanage);
app.panel_datamanage4.Position = [519 8 168 93];
% Create Label_2
app.Label_2 = uilabel(app.panel_datamanage4);
app.Label_2.HorizontalAlignment = 'right';
app.Label_2.Position = [56 64 53 22];
app.Label_2.Text = '单元格值';
% Create editfield_selectedcell_data
app.editfield_selectedcell_data = uieditfield(app.panel_datamanage4, 'numeric');
app.editfield_selectedcell_data.ValueDisplayFormat = '%.15f';
app.editfield_selectedcell_data.Position = [10 37 146 22];
% Create panel_datamanage3
app.panel_datamanage3 = uipanel(app.panel_datamanage);
app.panel_datamanage3.Position = [393 8 119 93];
% Create btn_findcol_data
app.btn_findcol_data = uibutton(app.panel_datamanage3, 'push');
app.btn_findcol_data.ButtonPushedFcn = createCallbackFcn(app, @btn_findcol_dataButtonPushed, true);
app.btn_findcol_data.Position = [19 8 79 23];
app.btn_findcol_data.Text = '查找';
% Create Label
app.Label = uilabel(app.panel_datamanage3);
app.Label.HorizontalAlignment = 'right';
app.Label.Position = [44 64 41 22];
app.Label.Text = '查找列';
% Create editfield_findcol_data
app.editfield_findcol_data = uieditfield(app.panel_datamanage3, 'text');
app.editfield_findcol_data.ValueChangedFcn = createCallbackFcn(app, @editfield_findcol_dataValueChanged, true);
app.editfield_findcol_data.Position = [10 36 100 22];
% Create panel_datamanage2
app.panel_datamanage2 = uipanel(app.panel_datamanage);
app.panel_datamanage2.Position = [260 8 126 93];
% Create btn_deleteall_data
app.btn_deleteall_data = uibutton(app.panel_datamanage2, 'push');
app.btn_deleteall_data.ButtonPushedFcn = createCallbackFcn(app, @btn_deleteall_dataButtonPushed, true);
app.btn_deleteall_data.FontColor = [1 0 0];
app.btn_deleteall_data.Position = [13 9 100 23];
app.btn_deleteall_data.Text = '清空';
% Create btn_deletecol_data
app.btn_deletecol_data = uibutton(app.panel_datamanage2, 'push');
app.btn_deletecol_data.ButtonPushedFcn = createCallbackFcn(app, @btn_deletecol_dataButtonPushed, true);
app.btn_deletecol_data.FontColor = [0.8667 0.3294 0];
app.btn_deletecol_data.Position = [13 35 100 22];
app.btn_deletecol_data.Text = '删除列';
% Create btn_deleterow_data
app.btn_deleterow_data = uibutton(app.panel_datamanage2, 'push');
app.btn_deleterow_data.ButtonPushedFcn = createCallbackFcn(app, @btn_deleterow_dataButtonPushed, true);
app.btn_deleterow_data.FontColor = [0.9608 0.4667 0.1608];
app.btn_deleterow_data.Position = [13 62 100 23];
app.btn_deleterow_data.Text = '删除行';
% Create panel_datamanage1
app.panel_datamanage1 = uipanel(app.panel_datamanage);
app.panel_datamanage1.Position = [7 8 245 93];
% Create Button_outputdatatoexcel
app.Button_outputdatatoexcel = uibutton(app.panel_datamanage1, 'push');
app.Button_outputdatatoexcel.ButtonPushedFcn = createCallbackFcn(app, @Button_outputdatatoexcelButtonPushed, true);
app.Button_outputdatatoexcel.Position = [132 24 100 23];
app.Button_outputdatatoexcel.Text = '导出到EXCEL';
% Create Button_importdatafromexcel
app.Button_importdatafromexcel = uibutton(app.panel_datamanage1, 'push');
app.Button_importdatafromexcel.ButtonPushedFcn = createCallbackFcn(app, @Button_importdatafromexcelButtonPushed, true);
app.Button_importdatafromexcel.Position = [132 63 100 23];
app.Button_importdatafromexcel.Text = '从EXCEL导入';
% Create Button_loaddata
app.Button_loaddata = uibutton(app.panel_datamanage1, 'push');
app.Button_loaddata.ButtonPushedFcn = createCallbackFcn(app, @Button_loaddataButtonPushed, true);
app.Button_loaddata.Position = [12 25 100 22];
app.Button_loaddata.Text = '加载数据';
% Create Button_savedata
app.Button_savedata = uibutton(app.panel_datamanage1, 'push');
app.Button_savedata.ButtonPushedFcn = createCallbackFcn(app, @Button_savedataButtonPushed, true);
app.Button_savedata.Position = [13 63 100 22];
app.Button_savedata.Text = '保存数据';
% Create UITable_data
app.UITable_data = uitable(app.Tab_datamanage);
app.UITable_data.ColumnName = {'Column 1'; 'Column 2'; 'Column 3'; 'Column 4'};
app.UITable_data.RowName = {};
app.UITable_data.ColumnEditable = true;
app.UITable_data.CellEditCallback = createCallbackFcn(app, @UITable_dataCellEdit, true);
app.UITable_data.SelectionChangedFcn = createCallbackFcn(app, @UITable_dataSelectionChanged, true);
app.UITable_data.Position = [28 20 1469 694];
% Show the figure after all components are created
app.UIFigure.Visible = 'on';
end
end
% App creation and deletion
methods (Access = public)
% Construct app
function app = app_01
% Create UIFigure and components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.UIFigure)
% Execute the startup function
runStartupFcn(app, @startupFcn)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFigure)
end
end
end
866

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



