Why guidata() doesn't work on an user function?

1 view (last 30 days)
Hi,
I have a variable stored in handles.switches.
I get into a callback function. I change this variable and at the end I execute guidata(hObject, handles) and this variable is updated. Fine.
The problem is if I update this variable in a user function inside this callback function. The handles.switches then is not updated although I execute at the end guidata(hObject, handles).
What can I do to update this variable inside other function?
I tried using set but it gives me an error. I am not using well this command.
>> set(handles.switches, 'UserData', work_comb);
Error using handle.handle/set
Invalid or deleted object.
But if I make a breakpoint at this line and write down handles.switches, the variable exists! I don't know what's going on...
Thanks!

Accepted Answer

Kevin Claytor
Kevin Claytor on 5 Dec 2012
Here's what's going on - guidata updates the handles structure in the function it's called in, but the user function that calls it still has an old version of guidata. You'll have to re-run guidata there to get the new version. Here's some pseudo-code that hopefully will make this clearer;
function callback(h, etc...)
% compute something and adjust handles there
handles.bob = 0;
sprintf('bob = %d',handles.bob) % returns 0
calculateBob(h);
sprintf('bob = %d',handles.bob) % returns 0 - doesn't have new handles
handles = guidata(h);
sprintf('bob = %d',handles.bob) % returns 55 - has the updated handles
function calculateBob(h)
handles = guidata(h);
handles.bob = 55;
guidata(h,handles);
Also you may want to consider getappdata() and setappdata() for storing variables instead of handles.
  3 Comments
Image Analyst
Image Analyst on 5 Dec 2012
Well it's not 100% clear to me. Is "callback" a custom written user function, like
function myCallBackFunction(input1, input2, input3)
or is it an automatically generated call back function like:
function pushbutton1_Callback(hObject, eventdata, handles)
? Since you didn't list the standard arguments by the standard names (hObject, eventdata, handles) I'll assume callback is a user function, not the automatic callback. So, if callback() is a user function, then since handles was not passed in in your code, when it does this:
handles.bob = 0;
it will be creating a new private local structure called handles that has nothing to do with the master one that the automatically generated callbacks see (they see it because it's passed in via the 3rd argument in the argument list). This local handles structure will have only the one field, not all the fields for the various controls that the master one has.
Now calculateBob is clearly a user function. When you call it, it gets h, which was passed in to callback() but not (yet) modified an any way. h does not have bob attached to it yet. So h goes into calculateBob. If callback() was called with handles as the first argument, then h is a copy of the master handles. In calculateBob, you pass h to guidata() to get a copy of the guidata and store it in a local copy of handles (because handles was not passed in and is therefore created automatically as a local variable.) This local copy should match the master copy, which does not yet have bob attached to it since callback() never attached bob to the master copy of handles. Then it attaches a bob field with value 55. So now the local copy of handles has a bob field, but the master handles still does not. Then calculateBob calls guidata() and tells it to stuff the local copy of handles into h. So now h will also now have a bob field just like the local copy of handles did.
What I'm not clear on is that since h is not passed out, but is it a copy of the master handles with bob now attached to it, will the master copy of handles match h?
What I usually do it to pass handles in and pass handles out, like Dani said in his "Answer".
function pushbutton1_Callback(hObject, eventdata, handles)
a = 123;
handles = MyFunction(handles, a);
% At this point, handles is just a local variable, not the master one.
% Update the master handles structure with local copy returned by
% MyFunction(). (this is GUIDE generate code)
guidata(hObject, handles);
% Function MyFunction takes in handles as a copy, adds bob, and passes the copy (not the master) back out
function handles = MyFunction(handles, a)
handles.bob = 55; % Add bob to local, private copy
fprintf('a=%d', a);
Though I admit I'm not clear on how stuffing handles into hObject updates handles, but this is the way that GUIDE does it because that's code GUIDE makes.
Marija Petrovic
Marija Petrovic on 24 Feb 2018
This was sooo helpful for me! Thank you!

Sign in to comment.

More Answers (1)

Dani Tormo
Dani Tormo on 5 Dec 2012
Ok, returning handles and saving them at the main callback function it works.
But still without knowing why guidata() doesn't work and set().

Categories

Find more on Loops and Conditional Statements 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!