Info

This question is closed. Reopen it to edit or answer.

How to choose data in nested struct array using popup menu while the number of field is different in each floor of the nested struct array ?

1 view (last 30 days)
Hello,
I have data organize in a nested struct array i.e : on the first floor of this struct I have different groups of data that are also themself struct array.
I wonder if it's possible to build a GUI that will allow the user to specify the data to be display but I may not necessarily have the same number of fields in each floor of my nested struct array so when choosing a field in the second floor I should keep in memory which field was selected on the first floor. To be more specific consider an example with three floor where on the first floor I have 2 struct array one whith 1 struct array with 2 fields to be display and a second with 2 struct array with respectively 3 and 4 fields to be display. So I wonder if it's possible to build a GUI with popup menu to allow the user to choose which filed to display ?
So far I have a small GUI with 3 popup menu and a draw button (plus some other draw option not important here) but when I change the selected value of the second popup menu I need to refere to the selected value of the first one in order to update the number of fields for the third popup menu. Here is the code I got :
cellgroup = cell(numel(fieldnames(data)),1); % first floor struct are call 'group'
for g=1:numel(fieldnames(data))
cellgroup{g} = ['Group ',num2str(g)];
end
Controlfig = figure('Name','Display control panel',...
'NumberTitle','off',...
'Units','pixels',...
'Position',[50 50 450 225]);
% Just some text do invite the user to choose fields
Textinfo = uicontrol('Parent',Controlfig,...
'Units','pixels',...
'Style','text',...
'String','Choose your display options :',...
'FontName','MS Sans Serif',...
'FontWeight','bold',...
'FontSize',12,...
'Position',[9 202 241 23]);
% Thrid floor fields to be display are called pulses
Pulsepopup = uicontrol('Parent',Controlfig,...
'Units','pixels',...
'Style','popupmenu',...
'String',{'Pulse 1'},...
'Enable','off',...
'Position',[9 85 127 27]);
% Second floor fields are called zones
Zonepopup = uicontrol('Parent',Controlfig,...
'Units','pixels',...
'Style','popupmenu',...
'String',{'Zone 1'},...
'Enable','off',...
'Position',[9 133 127 27],...
'Callback',{@chooseZone,Grouppopup,Pulsepopup,data});
% First floor fields are called groups
Grouppopup = uicontrol('Parent',Controlfig,...
'Units','pixels',...
'Style','popupmenu',...
'String',cellgroup,...
'Position',[9 168 127 27],...
'Callback',{@chooseGroup,Zonepopup,Pulsepopup,data});
% The push button to draw the data
Drawbutton = uicontrol('Parent',Controlfig,...
'Units','pixels',...
'String',{'Draw'},...
'Position',[145 4 130 22],...
'Callback',{@Datadraw,Grouppopup,Zonepopup,Pulsepopup,data});
% When the user choose a group update the possible fields to be selected in second and third floor
function chooseGroup(Grouppopup,Eventdata,Zonepopup,Pulsepopup,data)
set(Zonepopup,'Value',1)
set(Pulsepopup,'Value',1)
% One of the field is not a struct array but just some information
cellzone = cell(numel(fieldnames(data.(['Group_',num2str(Grouppopup.Value)])))-1,1);
for z=1:(numel(fieldnames(data.(['Group_',num2str(Grouppopup.Value)])))-1)
cellzone{z} = ['Zone ',num2str(z)];
end
% 5 fields of information here
cellpulse = cell(numel(fieldnames(data.(['Group_',num2str(Grouppopup.Value)]).(['Zone_',num2str(Zonepopup.Value)])))-5,1);
for p=1:(numel(fieldnames(data.(['Group_',num2str(Grouppopup.Value)]).(['Zone_',num2str(Zonepopup.Value)])))-5)
cellpulse{p} = ['Pulse ',num2str(p)];
end
% Allow the user to choose second and third floor field
set(Zonepopup,'String',cellzone)
set(Zonepopup,'Enable','on')
set(Pulsepopup,'String',cellpulse)
set(Pulsepopup,'Enable','on')
end
% Update third floor field when the user choose a second floor one
function chooseZone(Zonepopup,Eventdata,Grouppopup,Pulsepopup,data)
set(Pulsepopup,'Value',1)
grp = get(Grouppopup,'Value');
cellpulse = cell(numel(fieldnames(data.(['Group_',num2str(grp)]).(['Zone_',num2str(Zonepopup.Value)])))-5,1);
for p=1:(numel(fieldnames(data.(['Group_',num2str(grp)]).(['Zone_',num2str(Zonepopup.Value)])))-5)
cellpulse{p} = ['Pulse ',num2str(p)];
end
set(Pulsepopup,'String',cellpulse)
end
function Zonedraw(Drawbutton,Eventdata,Grouppopup,Zonepopup,Pulsepopup,data)
if allowdraw = strcmp(get(Zonepopup,'Enable'),'on');
% draw the data selected
else
disp('choose a group first')
end
end
So I understand why this could not work : because I refert to Grouppopup in Zonepopup callback before Groupopup has been define so I get this error when selecting a zone :
Error using matlab.ui.control.UIControl/get
Invalid or deleted object.
Error in LiveEditorEvaluationHelperESectionEval>chooseZone (line 652)
grp = get(Grouppopup,'Value');
Error while evaluating UIControl Callback.
But I realy don't know how I could possibly do otherwise, I would be very thankfull if you have any suggestion ?
  1 Comment
Geoffrey Schivre
Geoffrey Schivre on 17 Nov 2018
I found a way to remedy to my problem by passing the current group selected in second popup tag. But I'm still open to other solution !

Answers (0)

Tags

Products

Community Treasure Hunt

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

Start Hunting!