Adad Dayos
Adad Dayos

Reputation: 761

MATLAB: I am having trouble with a callback function

i have written a code which creates a figure with 3 buttons and a text box. the program complains about my callback function when i press a button though.

function game(states)

fig=figure('position',[200 150 500 370]);
face.B1=uicontrol('parent',fig,'style','pushbutton','string','start!','visible','on','position',[20 160 460 50]);
face.B2=uicontrol('style','pushbutton','parent',fig,'string','B2','visible','off','position',[20 90 460 50]);
face.B3=uicontrol('style','pushbutton','parent',fig,'string','B3','visible','off','position',[20 20 460 50]);
face.txtbx=uicontrol('style','text','parent',fig,'string','welcome to my game. press start to begin','position',[20 230 460 120]);

%set the callback function of the button
%when the button is pressed, i want to initiate the changestate function

set(face.B1,'callback','changestate(face,states,1);');

% while 1
    uiwait(fig)
% end

end

this is the function that i want to call when the button is pressed. the contents of this function are not important to my question, but i include it just in case

function face = changestate(face,states,nextstate)

disp('enter changestate')
    face.B1=set(face.B1,'string',states{nextstate}.B1str,'callback','changestate(face,states,states{nextstate}.B1next)');

if ~isnan(states(nextstate).B2str)
    face.B2=set(face.B2,'string',states{nextstate}.B2str,'callback','changestate(face,states,states{nextstate}.B2next)','visible','on');
else face.B2=set(face.B2,'visible','off');
end

if ~isnan(states(nextstate).B3str)
    face.B3=set(face.B3,'string',states{nextstate}.B3str,'callback','changestate(face,states,states{nextstate}.B3next)','visible','on');
else face.B3=set(face.B3,'visible','off');
end

face.txtbx=set(face.txtbx,'string',states{nextstate}.txtbxstr);
%     uiresume(fig)
end

the error that i am receiving is:

Error using waitfor Undefined function or variable 'face'.

Error using waitfor Error while evaluating uicontrol Callback

this error occurs when i press the button B1. I want the button to initiate the changestate function. can someone explain to me why i am getting this error?

Upvotes: 0

Views: 2563

Answers (1)

Werner
Werner

Reputation: 2557

When you use string declaration for a callback, it will be evaluated at the workspace callback scope. If you want your function to be evaluated with the variables at the current scope you should use one of the following:

…,'callback',@(~,~) changestate(face,states,states{nextstate}.B1next),...
…,'callback',@(hObj,evt) changestate(hObj,evt,face,states,states{nextstate}.B1next),...
…,'callback',{@changestate,face,states,states{nextstate}.B1next),...

instead of:

...,'callback','changestate(face,states,states{nextstate}.B1next),...

Where in the second and third callbacks, your function should be able to retrieve two more arguments, that are the button handle (hObj), and event data (evt), which will probably be empty.

The reason is the following, quoting here:

When MATLAB evaluates function handles, the same variables are in scope as when the function handle was created. (In contrast, callbacks specified as strings are evaluated in the base workspace.) This simplifies the process of managing global data, such as object handles, in a GUI.

Whereas when you use string:

Setting a callback property to a string causes MATLAB to evaluate that string in the base workspace when the callback is invoked.

As you used uiwait, execution stops inside uiwait (line 82) (for my matlab version), which has a waitfor command, giving the following error:

Error using waitfor
Undefined function or variable 'face'.

If you don't use a uiwait, it would evaluate the string callback at the global workspace, and the error would look like:

>> Undefined function or variable 'face'.

Error while evaluating uicontrol Callback

This discussion may also be of your interest.

Upvotes: 1

Related Questions