Updating handles from within Position Changed Callback

2 visualizaciones (últimos 30 días)
Stephen
Stephen el 15 de Jul. de 2014
Editada: Stephen el 17 de Jul. de 2014
I have defined an impoint roi object inside of an axis. I've set up the impoint with a callback for position changed function, and in that function I change the position of a second impoint as follows:
function positionChanged(pos)
handles = guihandles;
pointMoved = gco; %moving point is currently selected object
...
kids = get(pointMoved,'Children');
kids2 = get(correspondingPoint,'Children');
set(kids2(1),'Position',get(kids(1),'Position'));
set(kids2(1),'String',get(kids(1),'String'));
set(kids2(2),'XData',get(kids(2),'XData'));
set(kids2(2),'YData',get(kids(2),'YData'));
set(kids2(3),'XData',get(kids(3),'XData'));
set(kids2(3),'YData',get(kids(3),'YData'));
I'm just trying to get correspondingPoint to have the same values and positions as the point generating the callback, and the above works pretty well for this. The problem is that upon moving or resizing my figure window, all of those set values (minus the 'String' property, for some reason) revert, and my second impoint goes back to the position it had before the callback.
  2 comentarios
Sean de Wolski
Sean de Wolski el 15 de Jul. de 2014
My guess is that it's the gco. Can you get the handle from somewhere else?
Stephen
Stephen el 16 de Jul. de 2014
Hrm... now that I think about it you may be right, but I am not sure how I would go about getting that another way. I have an arbitrary number of points defined at runtime, so each of them would execute the same callback. The way MATLAB handles the interrupt I have no way of controlling the input arguments to see which point is responsible for the callback. Anyone have any ideas?

Iniciar sesión para comentar.

Respuesta aceptada

Alfonso Nieto-Castanon
Alfonso Nieto-Castanon el 15 de Jul. de 2014
Your figure might have a resizefcn callback that could be reverting those values. Check:
get(gcf,'resizefcn');
  7 comentarios
Alfonso Nieto-Castanon
Alfonso Nieto-Castanon el 17 de Jul. de 2014
Editada: Alfonso Nieto-Castanon el 17 de Jul. de 2014
I would do something like this:
f = impoint(gca,handles.lastPoint{1},handles.lastPoint{2});
setColor(f,color);
pos = getPosition(f);
setString(f,[num2str(pos(1)) ', ' num2str(pos(2))]);
%duplicate on the filtered axis
f2 = impoint(handles.axFiltered,handles.lastPoint{1},handles.lastPoint{2});
setColor(f2,color);
pos2 = getPosition(f2);
setString(f2,[num2str(pos2(1)) ', ' num2str(pos(2))]);
%ensure string gets updated if user interactively moves point
addNewPositionCallback(f,@(varargin)positionChanged(f,f2));
addNewPositionCallback(f2,@(varargin)positionChanged(f2,f));
The last two lines are the ones being modified. I am using that syntax to pass the impoint objects to the positionChanged function. Then you could have the function positionChanged something like:
function positionChanged(f1,f2)
pos=getPosition(f1);
setPosition(f2,pos);
end
And that will keep both impoint object positions "locked". Also note that if you have many impoint objects that want similarly locked (in pairs), you can just have one single positionChanged function that serves all of these, and define during the addNewPositionCallback call the appropriate parameters to pass to this function for each pair of impoint objects. Does this make sense?
Stephen
Stephen el 17 de Jul. de 2014
Editada: Stephen el 17 de Jul. de 2014
Yes, that makes sense and works well! I tried it out on a copy of my code, and seems to do it. That's a neat trick to be able to cast varargin. Much appreciated! I was also able to hack my way through the problem as in the answer below, but this is much simpler.

Iniciar sesión para comentar.

Más respuestas (1)

Stephen
Stephen el 17 de Jul. de 2014
While I did not solve the problem, I did come up with a work-around which does what I need, in case anyone comes after me has the same issues. I've found that if you first change the position of an impoint object inside of the callback as done in the original question, and then go through and create new impoint objects in their place, the changed position is stable so long as you're careful to keep the handles.impoint array updated. Here is the code inside of the position changed callback which does that, by iterating through the handles.impoints array:
handles = guihandles;
for i = 1:length(handles.impoint)
currentPoint = handles.impoint(i);
kids = get(currentPoint,'children');
%save everything to put into new point
x = get(kids(3),'XData');
y = get(kids(3),'YData');
string = get(kids(1),'String');
axis = get(currentPoint,'parent');
userData = get(currentPoint,'UserData');
color = get(currentPoint,'children');
color = get(color(2),'Color');
%don't overwrite the currently moving point
if i == pointMovedIdx
continue;
end
%otherwise, remake the point
h = impoint(axis,x,y);
setString(h,string);
setColor(h,color);
%add the correct callback based on which axis it's in
if axis == handles.axFiltered
%it's in axFiltered
addNewPositionCallback(h,@positionChangedFiltered);
%get the double handle
han = get(handles.axFiltered,'children');
han = han(1);
else
%it's in axUnfiltered
addNewPositionCallback(h,@positionChangedUnfiltered);
han = get(handles.axUnfiltered,'children');
han = han(1);
end
set(han,'UserData',userData);
handles.impoint(i) = han;
delete(currentPoint);
end
  1 comentario
Stephen
Stephen el 17 de Jul. de 2014
Also, see the answer above for a much simpler solution thanks to Alfonso!

Iniciar sesión para comentar.

Categorías

Más información sobre MATLAB Support Package for IP Cameras en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by