How to pass handle without using nested functions?

4 views (last 30 days)
I want to make a simple GUI programatically. Here is what I have done so far.
function main
% Initialize figure and axes
screenSize = get(0,'ScreenSize');
f = figure;
set(f, 'Visible','on', 'Resize','off', 'MenuBar', 'none', ...
'NumberTitle','off', 'Name','main', 'Units', 'pixels', ...
'Position',[1 1 0.6*screenSize(3) 0.6*screenSize(4)]);
movegui(f,'center');
a = axes;
set(a, 'Parent',f, 'Units','normalized', 'Position',[0.3 0.1 0.6 0.8]);
% Initialize uicontrols
pushButton = uicontrol('Style','pushbutton', 'String','Example', ...
'Units','normalized', 'Position',[0.1 0.1 0.1 0.1], ...
'Callback',@whenPushed);
% Initialize uimenus
fileMenu = uimenu('Label','File');
fileMenu_Save = uimenu('Parent',fileMenu, 'Label','Save', ...
'Callback',@saveContent);
fileMenu_Exit = uimenu('Parent',fileMenu, 'Label','Exit', ...
'Callback','close(''all'')');
end
function saveContent(fileMenu_Save, EventData)
[file,path] = uiputfile('animinit.m','Save file name');
end
function whenPushed(pushButton, EventData)
disp(pi);
end
When I click on Exit, the figure closes as I intended. But if there are several figures and I only want to close figure f, I must write close( f ) which MATLAB does not recognize. I can solve it by making a function instead of a string like this:
function main
...
fileMenu_Exit = uimenu('Parent',fileMenu, 'Label','Exit', ...
'Callback',@close_Callback);
...
function close_Callback(fileMenu_Exit, EvantData)
close(f);
end
end
But I would like to do this without nested functions. How can I solve then?

Accepted Answer

per isakson
per isakson on 23 Jun 2013
Edited: per isakson on 23 Jun 2013
Callbacks are invoked from the base workspace. Thus, the arguments passed when calling the callback-function must be in the base workspace. The figure handle, f, is in the main-function-workspace.
Your figure is the current figure when you click the file-menu. Thus, it is safe to use the function, gcf.
Try close(gcf) as in
fileMenu_Exit = uimenu('Parent',fileMenu, 'Label','Exit', 'Callback','close(gcf)');
What's wrong with nested the function? I cannot think of a better way to pass the handle, f. You can use userdata or appdata. GUIDE uses guidata which is a wrapper of appdata.It is possible to make the handle, f, available in the base workspace: assignin( 'base', ... )
Give the figure a good name, my_good_name, and use close( 'my_good_name' ) in the callback.
  3 Comments
per isakson
per isakson on 23 Jun 2013
Edited: per isakson on 23 Jun 2013
A few comments:
  • Design is little discussed in the Matlab fora
  • I think close( 'my_good_name' ) is a good way to close the figure. It is simple, robust and self-documented.
  • There is a "design pattern" sometimes called redblue, which is based on nested functions. See: GUI Examples using Nested Functions. I found that useful and it was my first choice for several years. (Now, I wrap the handle graphic objects in user classes - however that is often over-kill.) One nice thing with nested functions is that you can create function handles and pass these around to other functions like any other variable.
  • Did you check 41 Complete GUI Examples by Matt Fig.
  • avoid assignin. It's in the same category as eval, global, etc. And it a) litters the base workspace, b) makes the handle visible to the user, ... .
Zoltán Csáti
Zoltán Csáti on 23 Jun 2013
Thanks for the comments. I am currently watching Matt Fig's method and he also uses nested functions. This seems to be a proper way.

Sign in to comment.

More Answers (0)

Categories

Find more on Interactive Control and Callbacks in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!