MATLAB: Turning Handles Visibility Off In Nested Function

functionguihandleshomeworkuimenu

I've run into a problem.
I have a function that sets up a uimenu and initiates my GUI. When you click a button on the screen, the GUI sets the current objects on the screen off and runs a function I call in my callback function for that button (the function called in the callback function is a separate m file and contains the objects I want to display and their handles). I can successfully turn the objects on the first page off and turn the objects on the second page on. I run into problems when I try to run the menu for that page while that page is open. What I'm trying to do is take all the information I displayed on the page, set it visible off, and then redisplay the selection object that would then display the information I set visible off again.
Referring to the actual code:
I click on Info in the menu after I had already clicked on the button in the setup function (and therefore the infopage function was run) and after I had already clicked on value in the popup button. I tried setting output arguments, where the handles would be one of them, and then I could use
set(handle,'Visible','off')
but that doesn't seem to be working. If I remove all the set() lines I put into the code, the button selection goes back to the value 1 (in this case Alabama), but the other objects such as the flag are still being displayed. How can I get the value to go back to 1 and turn all of the other objects off (besides the directions and the stateselection)?
Here are my files-
setup.m
function setup
% This function initiates the entire project
% and sets us up on the title page
page = 1;
fh = figure('Visible','off',...
'Units','Normalized',...
'Position',[0 0 1 1],...
'MenuBar','None');
ax = axes('Units','Normalized',...
'Position',[0 0 1 1]);
flagbg = imread('https://upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/1280px-Flag_of_the_United_States.svg.png');
titleh = uicontrol('Style','Text',...
'Units','Normalized',...
'Position',[.3 .3 .4 .4],...
'FontName','ColonnaMT',...
'FontSize',60,...
'String','The United States of America');
subtitleh = uicontrol('Style','Text',...
'Units','Normalized',...
'Position',[.3 .3 .4 .2],...
'FontName','Garamond',...
'FontSize',20,...
'String','An Interactive Learning Tool');
buttonh = uicontrol('Style','pushbutton',...
'Units','Normalized',...
'Position',[.4 .4 .2 .05],...
'FontName','Ariel',...
'FontSize',20,...
'String','Click to begin...',...
'Callback',@info);
menulabel1 = uimenu('Label','Menu');
uimenu(menulabel1,'Label','Main Menu','Callback',@title);
uimenu(menulabel1,'Label','Info','Callback',@info);
uimenu(menulabel1,'Label','Assess','Callback','disp(''save'')');
uimenu(menulabel1,'Label','Compare','Callback','disp(''save'')');
uimenu(menulabel1,'Label','Help','Callback','disp(''save'')');
uimenu(menulabel1,'Label','Quit','Callback','close all',...
'Separator','on');
menulabel2 = uimenu('Label','Info');
uimenu(menulabel2,'Label','State Geography','Callback','disp(''figure'')');
uimenu(menulabel2,'Label','Flag Recognition','Callback','disp(''save'')');
menulabel3 = uimenu('Label','Assess');
uimenu(menulabel3,'Label','State Geography','Callback','disp(''figure'')');
uimenu(menulabel3,'Label','Flag Recognition','Callback','disp(''save'')');
menulabel4 = uimenu('Label','Compare');
uimenu(menulabel4,'Label','New Figure','Callback','disp(''figure'')');
uimenu(menulabel4,'Label','Save','Callback','disp(''save'')');
menulabel5 = uimenu('Label','Help');
uimenu(menulabel5,'Label','New Figure','Callback','disp(''figure'')');
uimenu(menulabel5,'Label','Save','Callback','disp(''save'')');
menulabel6 = uimenu('Label','Credits');
uimenu(menulabel6,'Label','%');
uimenu(menulabel6,'Label','%');
set(ax,'HandleVisibility','off',...
'Visible','off');
set(fh,'Visible','on')
function title(~,~)
close(fh)
setup
end
function [pages,handles] = info(~,~)
if page == 1
set(titleh,'Visible','off');
set(subtitleh,'Visible','off');
set(buttonh,'Visible','off');
[page,handles] = infopage;
elseif page == 2
[page,handles] = infopage;
set(handles.directions,'Visible','off')
set(handles.stateselection,'Visible','off')
set(handles.statename,'Visible','off')
set(handles.capital,'Visible','off')
set(handles.largestcity,'Visible','off')
set(handles.statehood,'Visible','off')
set(handles.population,'Visible','off')
set(handles.area,'Visible','off')
set(handles.nickname,'Visible','off')
set(handles.gdp,'Visible','off')
set(handles.flag,'Visible','off')
set(handles.axis,'Visible','off')
end
end
function home(~,~)
homepage;
end
end
infopage.m
function [page,handles] = infopage
page = 2;
handles = struct('directions',[],'stateselection',[],'statename',[],'capital',[],'largestcity',[],...
'statehood',[],'population',[],'area',[],'nickname',[],'gdp',[],'axis',[],'flag',[]);
StateStruct = loaderfn;
handles.directions = uicontrol('Style','text',...
'Units','Normalized',...
'Position',[0.12 .8 .25 .1],...
'FontSize',33,...
'FontName','Garamond',...
'String','What state do you want to learn about?');
handles.stateselection = uicontrol('Style','popup',...
'Units','Normalized',...
'Position',[0.18 0.65 0.13 0.1],...
'FontSize',17,...
'FontName','Garamond',...
'String',{StateStruct.Name},...
'Callback',@callbackfn);
%Set up the callback function to display selected state's data
function handles = callbackfn(source,~)
val = source.Value;
% Set up the state name display
statename = sprintf('%s (%s)',StateStruct(val).Name,StateStruct(val).Abbreviation);
handles.statename = uicontrol('Style','text',...
'Units','Normalized',...
'Position',[0.6 0.8 0.3 0.1],...
'String',statename,...
'FontSize',30,...
'FontName','TimesNewRoman');
% Set up the state info display
capital = sprintf('Capital: %s',StateStruct(val).Capital);
largestcity = sprintf('Largest City: %s',StateStruct(val).LargestCity);
statehood = sprintf('Year of Statehood: %s',num2str(StateStruct(val).Statehood));
population = sprintf('Population: %s',num2str(StateStruct(val).Population));
area = sprintf('Area: %s',num2str(StateStruct(val).TotalAreaMiles));
nickname = sprintf('Nickname: %s',StateStruct(val).Nickname);
gdp = sprintf('GDP: %s',num2str(StateStruct(val).GDP));
handles.capital = uicontrol('Style','text',...
'Units','Normalized',...
'Position',[0.5 0.7 0.5 0.1],...
'String',capital,...
'FontSize',20);
handles.largestcity = uicontrol('Style','text',...
---- %Snipped





handles.statehood = uicontrol('Style','text',...
---- %Snipped
handles.population = uicontrol('Style','text',...
---- %Snipped
handles.areah = uicontrol('Style','text',...
---- %Snipped
handles.nickname = uicontrol('Style','text',...
---- %Snipped
handles.gdp = uicontrol('Style','text',...
---- %Snipped
% Set up the flag display
url = StateStruct(val).Flag;
flag = imread(url);
handles.axis = axes('Units','Normalized',...
'Position',[0.05 0.10 0.4 0.5]);
handles.flag = imagesc(flag);
set(handles.axis,'Visible','off')
end
end

Best Answer

Hi Zachary - if I understand your problem correctly, once the user is on the info page that is displaying the dropdown list of states with (or without) the state flag and a description, then if the user presses the Info choice (from the Menu list) you are expecting the info callback to fire and set the visibility to off for the flag and description. Is this correct?
If I run your software under that assumption and I put a breakpoint at the info callback, I notice that the callback does fire and it tries to set the Visible property to off for these controls. And like you, I notice that nothing happens and the controls remain visible.
You need to look closely at this callback
function [pages,handles] = info(~,~)
if page == 1
set(titleh,'Visible','off');
set(subtitleh,'Visible','off');
set(buttonh,'Visible','off');
[page,handles] = infopage;
elseif page == 3
[page,handles] = infopage;
set(handles.directions,'Visible','off')
set(handles.stateselection,'Visible','off')
set(handles.statename,'Visible','off')
set(handles.capital,'Visible','off')
set(handles.largestcity,'Visible','off')
set(handles.statehood,'Visible','off')
set(handles.population,'Visible','off')
set(handles.area,'Visible','off')
set(handles.nickname,'Visible','off')
set(handles.gdp,'Visible','off')
set(handles.flag,'Visible','off')
set(handles.axis,'Visible','off')
end
end
If page is identical to 3 (which is the expected case here) then you call infopage to get the page number (?) and the handles associated with this page. The problem is that the majority of the handles within the handles structure are empty. Which makes sense given your call to infopage
function [page,handles] = infopage
page = 3;
handles = struct('directions',[],'stateselection',[],'statename',[],'capital',[],'largestcity',[],...
'statehood',[],'population',[],'area',[],'nickname',[],'gdp',[],'axis',[],'flag',[]);
The only valid (non-empty) handles are those to directions and stateselection. So you would think that at least these two would be hidden, right? Except (!) there is a problem - every time you call infopage you are re-creating this handles structure and re-creating the controls which will have different handles than those that are presently shown on your GUI. So you will never be able to hide them because you are adding new controls over top of the existing ones.
You only want to call infopage once to initialize all controls for this page (hiding all) and then saving all of these infoPageHandles within your setup function so that you can reference them later.
For example, in your setup function you would do something like (after creating all controls for the first page)
% create the infopage
[infoPageHandles] = infopage;
and then your info callback would look like
function [pages,handles] = info(~,~)
if page == 1
set(titleh,'Visible','off');
set(subtitleh,'Visible','off');
set(buttonh,'Visible','off');
page = 3;
set(infoPageHandles.directions, 'Visible', 'on');
set(infoPageHandles.stateselection, 'Visible','on');
elseif page == 3
set(infoPageHandles.directions,'Visible','on')
set(infoPageHandles.stateselection,'Visible','on')
set(infoPageHandles.statename,'Visible','off')
set(infoPageHandles.capital,'Visible','off')
set(infoPageHandles.largestcity,'Visible','off')
set(infoPageHandles.statehood,'Visible','off')
set(infoPageHandles.population,'Visible','off')
set(infoPageHandles.area,'Visible','off')
set(infoPageHandles.nickname,'Visible','off')
set(infoPageHandles.gdp,'Visible','off')
cla(infoPageHandles.axis);
end
end
We use cla to clear the axis of the image (flag) that has been drawn to it. (You have to be careful here as each time you load the flag, you are "drawing" one over top of the other. Whenever you draw a new flag, you should delete or clear out the old.)
As for the infopage function, see the attached. Note that you will have to handle the current page number from within your setup function (or perhaps rename this to main).