GUIDATA updating "handles" in GUIDE with nested functions

5 views (last 30 days)
This is an extension to a current question answered by Geoff Hayes and Walter Roberson:
Attached you can find a simple GUIDE with 2 push buttons:
Button #1 plots a sine graph.
Button #2 adds a "movable" vertical line to the graph.
Everything works fine and I can drag vertical line as desired (Thanks to Geoff and Walter)
What I'm trying to do now is to record x-position of vertical line (x_history) as I move it, and save this x_history to handles (via guidata) such that if I stop moving the line (mouse-up) and then resume moving the line (mouse-down and mouse-move) I can restore previous x_history from handles (via guidata).
The problem I'm facing is that every time I stop moving the line and go mouse-up, handles resets(!) the x_history field (removes the field), so I loose the previous record of x_history when I resume mouse-down and move the line.
What am I missing here?

Accepted Answer

Jan on 6 Aug 2017
Edited: Jan on 6 Aug 2017
This is a confusing mixture of storing the handles struct in two figures by guidata, using handles from the inputs of the callbacks (where it is a static copy of the contents from this struct at the time of the creation of the callback), and the common using of local variables in nested functions. This is more complexity than you require.
Decide for one mechanism to share the handles struct, e.g. in the figure's ApplicationData by using guidata and prefer the figure, which contains the activated object. Then insert this in each callback:
function XYZ_Callback(hObject, EventData, handlesFromInput)
handles = guidata(hObject);
guidata(hObject, handles);
Convert the nested functions to "non-nested normal" (how is it called?) function and use the input hObject.
In addition the guidata concern the figure, which contain the figure with the two buttons, not the figure, which contains the diagram and the moved line. Better keep your data locally in the figure, which is processed.
By the way: I could not reproduce your observation:
The problem I'm facing is that every time I stop moving the line and go
mouse-up, handles resets
How and where do you observe this?
  1 Comment
Alborz Sakhaei
Alborz Sakhaei on 6 Aug 2017
Appreciate your time.
Here is a more detail description of the problem:
As I click on the line and drag it, the "x_history" variable records the x coordinate of vertical line. i.e. the length of "x_history" increase by adding new x coordinates to it. This variable is being saved into handles via guidata. Now I stop moving, release the mouse (mouse-up) and then click on the line and start to drag it again. Problem is that at this stage I would like to retrieve the previous x_history vector and continue adding x coordinates to it. But what I get when I start to drag the line is handles.x_hisory=[]. That's what I meant by "handles resets x_history field".
Given your excellent hint, I think I figured what I've been missing:
In the mouseDown callback (the nested function in pushbutton_vertline_Callback), I was missing to get the updated copy of handles. So, I needed to add this line to that nested function:
handles = guidata(hObject);
This resolves the issue so every time I resume dragging the line I can retrieve the previous record of x_history.
Now my question is answered (thanks :)), but I'm still a bit confused about your comment on complexity of the code. I am not using handle of the nested function anywhere within the code. As you can see all input arguments of the nested functions are replaced by ~. So, anytime I grab handles it's the one that is being retrieved from guidata. So, do you still recommend to change the nested functions to " non-nested normal" functions?

Sign in to comment.

More Answers (0)


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!

Translated by