Why is guidata not working for me??

15 views (last 30 days)
jmp448
jmp448 on 13 Jun 2016
Commented: jmp448 on 13 Jun 2016
I have looked through so many similar past questions and answers, I know this is a common problem, but I just cannot figure out what it is that I am doing wrong. PLEASE help me out. All I want to do is update the 'handles' structure in a user function, rather than in a pre-existing callback function. I created a simplified code that should allow me to do this:
% --- Executes on button press in Calculate.
% This is the pre-existing function, built into the GUI
function Calculate_Callback(hObject, eventdata, handles)
% hObject handle to Calculate (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Here I call the user function
NewValFunction(hObject, eventdata, handles)
% Here I display handles, which SHOULD have been updated according to the user function by now
handles
% And the rest is just the stuff that the GUI does (no problems here)
Radius = get(handles.Radius, 'Value');
AreaVal = Radius^2 * pi;
set(handles.Area, 'String', AreaVal);
% Here is the function: I call all the necessary stuff
function NewValFunction(hObject,eventdata,handles)
% Get the handles structure
handles = guidata(hObject);
% Make a simple change to the handles structure
handles.NewValue = 2;
% Display the handles structure
handles
% And save the handles structure
guidata(hObject,handles);
Now as you can see, I display handles right after I have updated it within the user function, and then I display it again right after the user function has been completed. I thought that since I included guidata(hObject, handles) at the end of my user function, it should update handles permanently. But it doesn't! Handles displays the new field within the function, but the second time I display handles (outside the user function), the new field doesn't show up. This is only a problem if I did not previously have the GUI figure open; if the program was already open and is just being run again, then everything is fine and handles is properly updated. Can anyone please explain this??

Accepted Answer

Adam
Adam on 13 Jun 2016
Edited: Adam on 13 Jun 2016
The problem here is that handles is a struct and is copied by value, not updated by reference. Whenever you access handles you basically take a time-stamped version of it.
In Calculate_Callback you get the handles struct passed into your function. You then call your user function (by the way, don't pass handles or eventdata to this if you are doing it your way, it just adds confusion) and put those handles back into the GUI.
However, when your code flow returns to Calculate_Callback you then locally have the version of handles that was passed into that function still. This is no longer the up to date version that is stored in the GUI. If Calculate_Callback runs to completion without itself calling guidata( hObject, handles ) to write handles back to the GUI then you will still have the version of handles you expect stored in the actual GUI, just not in the remainder of that Calculate_Callback function.
You can do either of the following:
  • Add the following line after NewValFunction(hObject, eventdata, handles) to ensure it picks up the very latest version of handles:
handles = guidata( hObject )
  • Change your user function so that it takes in handles and returns handles rather than it getting and setting handles from hObject - i.e.
function handles = NewValFunction( handles )
% Make a simple change to the handles structure
handles.NewValue = 2;
% Display the handles structure
handles
Generally I take the 2nd approach because it is simpler though I do not like it much either so in more recent GUIs I have been delegated almost everything to a class that controls things rather than the handles structure.
The 1st approach is ugly too though is it relies on your code knowing what the user function is doing and that it has to update its handles after calling it. This I have done on odd occasions too, but usually when I have complicated callback-listener setups that are editing the handles structure before code returns to my original callback function.
  1 Comment
jmp448
jmp448 on 13 Jun 2016
Thank you very much, that makes a lot of sense

Sign in to comment.

More Answers (0)

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!