2

Background

In Python and JS we have closures, which returns a function with some of the variables pre-defined. e.g.

def make_printer(msg):
    def printer():
        print msg
    return printer

Do we have similar stuff in Matlab?

Here I have a callback function

function show(object, eventdata)

that is to be set to the callback of my GUI

func = @show;
set(gcf, 'WindowButtonMotionFcn', func);

However, I want to add some additional parameters to this show function.

Currently I'm using global variables to do that. But I think it would be elegant if we have a 'closures function'.

About anonymous function

Yes we do have anonymous function in Matlab. However it seems to me that it is too simple to support 60-line procedures.

1
  • 1
    I'm not sure I quite understand your question, but in case this helps before someone more knowledgable comes along, I'll make a suggestion. You can add an additional argument to a callback function, function callbackFunction(object,eventdata,variable). You may be able to add multiple extra arguments I haven't tried, I make a struct with all of the variables used by my GUI and just use it as the third input argument. Hope that is relevant! Commented Mar 25, 2014 at 4:48

3 Answers 3

2

There was once a document floating about the internet by Sergey Simakov. It was very terse , not especially descriptive but covered the bases. This was in my experience the most authoritive text on matlab GUI's. I suspect it still is ...

You're solving two/three problems :

Closure Problem

Nested functions resolve this problem.

function iterator = count(initial)
 % Initialize
 if ~exist('initial','var')
  counter = 0
 else
  counter = initial
 end
 function varargout = next() % [1] 
  % Increment
  counter = counter + 1
  varargout = {counter}      % [1] 
 end
 iterator = @next
end

Note(s) :

  1. One may not simply return counter ! It must be wrapped in varargout or assigned to some other output variable.

Usage

counter = count(4) % Instantiate
number = counter() % Assignment
number = 
  5

Closed Scope + State problem

No ugly braces, worrying about scope, cell arrays of strings. If you need access to something it's under SELF no more FINDOBJ, USERDATA, SET/GETAPPDATA, GLOBAL nonsense.

classdef Figure < handle

 properties 
  parent@double
  button@double
  label@double
  counter@function_handle
 end

 methods 
  function self = Figure(initial)
   self.counter = count(initial) % [1]
   self.parent  = figure('Position',[200,200,300,100])
   self.button  = uicontrol('String','Push',          'Callback', @self.up, 'Style', 'pushbutton', 'Units', 'normalized', 'Position', [0.05, 0.05, 0.9, 0.4])
   self.label   = uicontrol('String', self.counter(),                       'Style', 'text',       'Units', 'normalized', 'Position', [0.05, 0.55, 0.9, 0.4])
  end

  function up(self,comp,data)
   set(self.label,'String',self.counter())
  end
 end
end

Note(s):

  1. One uses the function listed in the Closure problem above

Usage :

f = Figure(4)                  % Instantiate
number = get(f.label,'String') % Assign
number = 
  5

You may prefer :

f.label.get('String')          % Fails (f.label is double not handle, go figure)
h = handle(f.label)            % Convert Double to handle
number = h.get('String')       % Works 
number = 
  5
Sign up to request clarification or add additional context in comments.

Comments

1

Since it looks like my comment was helpful, I'll explain what I mean about the struct thing. I think the way you are calling the callback functions is slightly different, so this may not work so well).

If you have a bunch of different callback functions, and a bunch of variables you want to pass to them, it is annoying and difficult to have a big list of input arguments for each function. Instead, I do something like this:

First create a bunch of UI components , but don't specify their callback functions, e.g

radio1_handle=uicontrol(panel1_handle,'Style','radiobutton',...
    'Min',0,'Max',1,'Value',0,'Units','normalized','Position',[.8 .8 .2 .25]);

once you have made all the components, create a struct of variables you will be using

vars=struct('varName1',var1,'varName2',var2);

then update the UI components to include the callback functions

set(radio1_handle,'Callback',{@radio1_callback,vars});

now create the actual functions

function radio1_callback(object,eventData,vars)

So it's nothing fancy, just a potentially neater way than using multiple arguments.

Comments

1

Inspired by this question and @David's comment, I came up with the solution. (Maybe this is @David's answer, but not explicitly explained. So let me extend his comment into an answer.)

There is actually a way to add extra parameters to callbacks.

Just add the parameters to the end of the parameter list

function show(object, eventdata, extra)

and set the callback like this:

func = @show;

set(gcf, 'WindowButtonMotionFcn', func);

Reference

Mathworks

Passing Additional Input Arguments

You can define the callback function to accept additional input arguments by adding them to the function definition:

function myCallback(src,eventdata,arg1,arg2)

When using additional arguments for the callback function, you must set the value of the property to a cell array (i.e., enclose the function handle and arguments in curly braces):

figure('WindowButtonDownFcn',{@myCallback,arg1,arg2})

3 Comments

Cool. I added an answer explaining what I meant, but I think you have the complete solution here.
Pretty much the same. Actually the callback can get several extra parameters, so no bother the struct. Am I right on this?
Yep. The only reason to use a struct is that if you change the code you don't have to update a whole bunch of variables in a whole bunch of functions. I was working with about 15 variables in each of about 10 callback functions, and putting them in a struct just made it easier to manage.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.