How can I update the values of a "handles" struct, if I want to use a function, in MATLAB GUI?

For example I set the following listener for hUE(n) to ButtonDownFcn when the user click on the object (which the handle is hUE(n)), the removeUE is called and sends the "handles" struct to it:
set(hUE(n),'ButtonDownFcn',{@removeUE,handles});
I have used the global variables to store the values of hUE and update it in the function as you see below:
function removeUE(src,evnt,handles)
global UECounter;
global hUE;
global flag;
if strcmp(flag,'removeUE')
hUE = hUE(hUE ~= src);
delete(src);
UECounter = UECounter - 1;
end
My question is how can I store the values of hUE(n) in the "handles" struct and get rid of the global variables?

Answers (1)

if strcmp(handles.flag,'removeUE')
handles.hUE = handles.hUE(handles.hUE ~= src);
handles.UECounter = handles.UECounter - 1;
guidata(src, handles);
delete(src);
end

4 Comments

Thanks Walter. I checked this method and it does not update handles if the function is called by an event.
Yes it does. However, if the event occurs during the middle of execution of another routine, that other routine's notion of "handles" will not be updated until that routine asks for an update by using
handles = guidata(AppropriateFigureNumber);
The "handles" that is passed into a routine should be treated like a photocopy of the "master" copy of the information. You can mark up the photocopy all you want, and you can make the master a copy of your marked-up version, but anyone else who photocopies the master version will not get your changes until you post the changes to the master and the other person goes back and asks for a new copy.
So what is the solution in this case which ButtonDownFcn event calls the removeUE during the execution of another routine? I have already implemented it using the global variables.
Here is the code from the button group which contains 5 radio button:
function UEControl_SelectionChangeFcn(hObject, eventdata, handles)
% hObject handle to the selected object in UEControl
% eventdata structure with the following fields (see UIBUTTONGROUP)
% EventName: string 'SelectionChanged' (read only)
% OldValue: handle of the previously selected object or empty if none was selected
% NewValue: handle of the currently selected object
% handles structure with handles and user data (see GUIDATA)
global UECounter;
global hUE;
global flag;
switch get(eventdata.NewValue,'Tag') % Get Tag of selected object.
case 'addUE'
flag = 'addUE';
set(handles.axes1,'ButtonDownFcn',{@addUE,handles});
case 'removeUE'
flag = 'removeUE';
if UECounter >= 1
for n = 1:UECounter
set(hUE(n),'ButtonDownFcn',{@removeUE,handles});
end
end
case 'setTXUE'
flag = 'setTXUE';
if UECounter >= 1
for n = 1:UECounter
set(hUE(n),'ButtonDownFcn',{@setTXUE,handles});
end
end
case 'setRXUE'
flag = 'setRXUE';
if UECounter >= 1
for n = 1:UECounter
set(hUE(n),'ButtonDownFcn',{@setRXUE,handles});
end
end
case 'setCUE'
flag = 'setCUE';
if UECounter >= 1
for n = 1:UECounter
set(hUE(n),'ButtonDownFcn',{@setCUE,handles});
end
end
end
% Update handles structure
guidata(hObject, handles);
And here is the code for the addUE:
function addUE(src,evnt,handles)
% src - the object that is the source of the event
% evnt - empty for this property
global UECounter;
global hUE;
global flag;
global positionUE;
position = get(handles.axes1,'CurrentPoint');
if strcmp(flag,'addUE')
UECounter = UECounter + 1;
positionUE(1,UECounter) = position(1,1);
positionUE(2,UECounter) = position(1,2);
hUE(UECounter) = drawCircle([position(1,1) position(1,2)],handles.UESize);
end
And finally the code for removeUE is:
function removeUE(src,evnt,handles)
global UECounter;
global hUE;
global flag;
global positionUE;
if strcmp(flag,'removeUE')
indTmp = sum((1:length(hUE)).*(hUE == src));
if indTmp == 1
positionUE = positionUE(:,2:end);
elseif indTmp == length(hUE)
positionUE = positionUE(:,1:end-1);
else
positionUE = positionUE(:,[1:indTmp-1 indTmp+1:end]);
end
hUE = hUE(hUE ~= src);
delete(src);
UECounter = UECounter - 1;
end
When you use
set(handles.axes1,'ButtonDownFcn',{@addUE,handles})
you are setting the argument to be passed in to addUE to be a copy of the handles structure as it is at the time the ButtonDownFcn is set(). That is not what you want. So instead of passing in handles, pass in the figure number of the GUI, and inside each of those routines use
handles = guidata(ThePassedFigureNumber);
and then if the routine updates handles,
guidata(ThePassedFigureNumber, handles);

Sign in to comment.

Categories

Find more on Interactive Control and Callbacks in Help Center and File Exchange

Asked:

on 30 Apr 2013

Community Treasure Hunt

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

Start Hunting!