Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

How to pass handle without using nested functions?

Asked by Zoltán Csáti on 23 Jun 2013

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?

0 Comments

Zoltán Csáti

Products

1 Answer

Answer by per isakson on 23 Jun 2013
Edited by per isakson on 23 Jun 2013
Accepted answer

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

Zoltán Csáti on 23 Jun 2013

Thank you, I did not notice that callbacks are invoked from the base workspace up to now. I am novice in graphics programming but in my opinion nested functions are not desirable if for example an embedded function must be used not only within the function where we nested it, but inside an another function. Can we use it then? So what do you recommend me: * use nested functions * use assignin * use the UserData field ? What are the advantages and/or disadvantages of the methods above?

Thank you very much.

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 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.

per isakson

Contact us