MATLAB: Handles structure doesn’t get updated or updates badly

guidehandles

I have developed a Gui using Guide for medical image data analysis. When I put breakpoints to check each line of the code, I get some wired problems.
In Brief,
There is a pushbutton and whenever the user clicks it, a ROI is drawn on the image. there is a counter that counts the number of ROIs drawn and differentiates between them by assigning a unique tag to each plot object. I have assigned windows button motion and UIcontext menu to each plot object. So that the user can drag the ROI using the mouse and place it in the location of interest and also the user can rename or delete an already drawn ROI. The number of the ROIs present depends on the number of the time the user clicks the pushbutton.
I put some break points in the rename callback function (uicontext menu) to check the functionality of the code and this is where the handles structure gets updated in a strange manner. Let's say, there are 5 ROIs in the image (each ROI object has a unique tag specified by a counter), when the user selects for example the 2nd ROI, the handles structure only shows the first 2 plot objects, if the user selects the 4th ROI, the handles structure only shows the first 4 plot objects and so on.
This results in the handles structure to get updated strangely and not properly.
I have hard time understanding what is going on.
I hope I have explained my problem clearly.
Here is the code I have written. Sorry in advance it is a long code:

Best Answer

Without reading the code, I can predict what is happening.
When you create a callback using the {} syntax, such as
'Callback', {@Pushbutton1_Callback, handles}
then the value of the variable that will be passed in as a parameter is the value that the variable had at the time the callback is constructed. A copy of the value is "captured", almost exactly the same way as if you had constructed
pbc = @(src, event) Pushbutton1_Callback(src, event, handles);
and then had used
'Callback', pbc
In constructing the function handle, the current value of the handles variable is captured and would be used for all calls to the routine. The internal mechanism works a little differently for constructing callbacks but the effect is the same.
Therefore if you have a setup similar to
handles = struct();
handles.button1 = uicontrol('String', 'first' ,'Callback', {@routine1, handles});
handles.button2 = uicontrol('String', 'second' ,'Callback', {@routine2, handles});
handles.button3 = uicontrol('String', 'third' ,'Callback', {@routine3, handles});
then the handles that would be captured for use in the callback to routine1 would be the empty structure assigned the line before. Then, the uicontrol being fully constructed the handle of the uicontrol would be put into the handles structure, leaving it with one field. It would then be that handles with one field that was captured for use in the callback to routine2, and then the uicontrol construction complete its handle would be assigned into handles leaving handles with two fields. And that would be the handles that was captured for use with routine3. And so on.
There are at least two work-arounds. The easier of them is like this:
handles = struct();
handles.button1 = uicontrol('String', 'first');
handles.button2 = uicontrol('String', 'second');
handles.button3 = uicontrol('String', 'third');
set(handles.button1, 'Callback', {@routine1, handles});
set(handles.button2, 'Callback', {@routine2, handles});
set(handles.button3, 'Callback', {@routine3, handles});
This constructs handles with all of the controls first, and then it is that fully-completed handles that is captured when the callbacks are created. Remember, though, that exactly the same problem would arise with respect to anything else you assigned into handles at any time after the callback is constructed.
The more tedious but more robust of the work-arounds is to not pass in the handles structure, and instead pass in whatever information is needed to locate the handles structure. If you use guidata() to record a master copy of the handles structure, then what you need to pass in is the handle of any graphics object that is at or underneath the figure that the guidata() is hanging its data off of. In the simplest case where you only have controls on one figure and the guidata is attached to that figure, then you do not need to pass in anything extra:
function routine1(src, event)
handles = guidata(src);
with no third parameter needed. But if there are controls over multiple figures then you need to pass in the appropriate figure:
fig = gcf;
handles.button1 = uicontrol('String', 'first' ,'Callback', {@routine1, fig});
...
function routine1(src, event, fignum)
handles = guidata(fignum);
Related Question