Update data in uitable in second tab from button callback in first tab

Hi, I am new to Matlab and still getting the hang of building an app programmatically.
I would like to update the data in a uitable based on the information supplied in a "setup" tab. In this simple example, the user can either select to calculate weights based on the number of iterations or can enter the weights manually.
I have tried to methods:
  • Create the uitable with a tag, use findobj to get the uitable and then set the data, but that returned an empty graphics place holder.
  • Create the tab with the uitable first and then send the uitable as a parameter to the button callback. This is the code shown below.
Any help will be much appreciated!
function [weights, NIter, calcWeights] = simpleApp()
function editFieldChanged(src)
NIter=src.Value;
end
function checkBoxChanged(event)
calcWeights=event.Value;
end
function parButtonPushed(src,event,tab)
if calcWeights
[weights] = repelem(1/NIter,NIter)';
k=findobj('Tag', 'weights'); % Returns empty GraphicsPlacerHolder and then error
tab.Data=weights; % No error but data is not updated in the second tab.
end
end
%% Main GUI function
% Set default values
calcWeights=false;
NIter=10;
fig = uifigure;
fig.Position(4)=250;
movegui(fig,'center');
tabgp = uitabgroup(fig);
tab1 = uitab(tabgp,"Title","Set Up");
tab2= uitab(tabgp,"Title", "Weights");
% Create second tab containing uitable
g2 = uigridlayout(tab2, [1,1]);
g2.RowHeight = {30};
g2.ColumnWidth = {'fit'};
test=zeros(NIter,1);
t1w=array2table(test,"RowNames",string(linspace(1,NIter,NIter)), "VariableNames",{'Weight'});
t11w=uitable(g2,"Data",t1w,'Tag','weights');
t11w.ColumnEditable = repelem(~calcWeights,1);
t11w.Layout.Row=2;
t11w.Layout.Column=1;
% Create first tab containing set up parameters
g = uigridlayout(tab1,[3,2]);
g.RowHeight = {22,22,22};
g.ColumnWidth = {'fit',50};
cbx=uicheckbox(g, "Text","Calculate weights?","Position",[10,10,500,22]);
cbx.Layout.Row=1;
cbx.Layout.Column=1;
cbx.ValueChangedFcn = @(src,event) checkBoxChanged(event);
lbltab1=uilabel(g,"Text","Number of iterations");
lbltab1.Layout.Row=2;
lbltab1.Layout.Column=1;
eftab1=uieditfield(g,'numeric');
eftab1.Layout.Row=2;
eftab1.Layout.Column=2;
eftab1.Value=NIter;
eftab1.ValueChangedFcn = @(src,event) editFieldChanged(src);
btab11=uibutton(g,'Text','Continue',"ButtonPushedFcn", @(src,event) parButtonPushed(t11w));
btab11.Layout.Row=3;
btab11.Layout.Column = 1;
end

 采纳的回答

Hi,
to be honest, I am not sure why your code line returns the empty graphics placeholder. A fix however would be:
k=findobj(fig, 'Tag', 'weights')
Also if that's what you intend, be sure to use that object in the next line:
k.Data=weights;
Personally, I find it a lot easier to use App Designer. If you want to get started with it, take this free Onramp:
Best wishes,
Harald

1 个评论

Thank you - your solution worked and is neater than my "fix".
The layout of the actual app that I am building depends on user inputs so I am finding it easier to do it programmatically. However, I will go through the Onramp and see if I can do the same with the App Designer.

请先登录,再进行评论。

更多回答(1 个)

I have figured it out - silly mistake on my side. Leaving the answer here in case it helps someone else battling with the same problem.
When I send the parameters to the callback, I only sent one parameter, while the callback function expected 3, so the callback function took the first parameter as the table to change. A simple change to set src.Data=weights rather than tab.Data=weights worked.
function [weights, NIter, calcWeights] = simpleApp()
function editFieldChanged(src)
NIter=src.Value;
end
function checkBoxChanged(event)
calcWeights=event.Value;
end
function parButtonPushed(src)
if calcWeights
[weights] = repelem(1/NIter,NIter)';
k=findobj('Tag', 'weights');
src.Data=weights;
end
end
%% Main GUI function
% Set default values
calcWeights=false;
NIter=10;
fig = uifigure;
fig.Position(4)=250;
movegui(fig,'center');
tabgp = uitabgroup(fig);
tab1 = uitab(tabgp,"Title","Set Up");
tab2= uitab(tabgp,"Title", "Weights");
g2 = uigridlayout(tab2, [1,1]);
g2.RowHeight = {30};
g2.ColumnWidth = {'fit'};
test=zeros(NIter,1);
t1w=array2table(test,"RowNames",string(linspace(1,NIter,NIter)), "VariableNames",{'Benchmark Weight'});
t11w=uitable(g2,"Data",t1w,'Tag','weights');
t11w.ColumnEditable = repelem(~calcWeights,1);
t11w.Layout.Row=2;
t11w.Layout.Column=1;
g = uigridlayout(tab1,[3,2]);
g.RowHeight = {22,22,22};
g.ColumnWidth = {'fit',50};
cbx=uicheckbox(g, "Text","Calculate weights?","Position",[10,10,500,22]);
cbx.Layout.Row=1;
cbx.Layout.Column=1;
cbx.ValueChangedFcn = @(src,event) checkBoxChanged(event);
lbltab1=uilabel(g,"Text","Number of iterations");
lbltab1.Layout.Row=2;
lbltab1.Layout.Column=1;
eftab1=uieditfield(g,'numeric');
eftab1.Layout.Row=2;
eftab1.Layout.Column=2;
eftab1.Value=NIter;
eftab1.ValueChangedFcn = @(src,event) editFieldChanged(src);
btab11=uibutton(g,'Text','Continue',"ButtonPushedFcn", @(src,event) parButtonPushed(t11w));
btab11.Layout.Row=3;
btab11.Layout.Column = 1;
end

类别

帮助中心File Exchange 中查找有关 Develop Apps Programmatically 的更多信息

产品

版本

R2025a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by