Accessing an ROI move listener in another function so to delete it

5 views (last 30 days)
Hello.
I am using listeners to allow a user to reshape an ellipse ROI (i.e. orange shape) to then apply a mask to an image (then perfrom analysis on that part of the image). I'm using appdesigner
I store the centre and radius of the ROI as global variables (public properties)
I have a pushbutton that allows the user to view and change the shape of the ROI. This is my code.
%get current stored ROI ellipse parameters
r=app.ROIradius;
xc=app.ROIxc;
yc=app.ROIyc;
ax=app.UIAxes3; %This is the UIAxes my image is on.
IM=double(getimage(ax));
[sy,sx]=size(IM);
%Delete any previous ROI
t=findobj(ax,'Type','images.roi.Ellipse');
delete(t);
%Draw ROI using current saved parameters and add a listener to allow it to be changed
h = images.roi.Ellipse(ax,'Center',[xc yc],'Semiaxes',[r r],'Color','r','StripeColor','g','LineWidth',1); %1/e^2 = 1.699xfwhm
h.FaceAlpha = 0.3;
h.DrawingArea=[1 1 sx sy];
h.FixedAspectRatio=true; %ensure a circle
% Listen for mouse movement of the ROI
l=addlistener(h,'MovingROI',@app.allevents);
Then in my allevents function that is attached to the listener: (Perhaps I should have a MovedROI, rather than moving?)
function allevents(app,src,evt)
evname = evt.EventName;
switch(evname)
case{'MovingROI'}
disp(['ROI moving Current Center: ' mat2str(evt.CurrentCenter)]);
disp(['ROI moving Current SemiAxes: ' mat2str(evt.CurrentSemiAxes)]);
c=evt.CurrentCenter;
app.ROIxc=c(1);
app.ROIyc=c(2);
r=evt.CurrentSemiAxes;
app.ROIradius=r(1);
...
case ..
end
I then have another button to create the mask.
r=round(app.ROIradius); xc=round(app.ROIxc); yc=round(app.ROIyc);
circ = drawcircle('Center',[xc,yc],'Radius',r);
BW = createMask(circ,IM);
figure
subplot(1,2,1)
imshow(BW)
IM(~BW) = 0 ; %Apply the mask
subplot(1,2,2)
hi=0.8*max(IM(:))
lo=min(IM(:))
imshow(IM,[lo hi])
My issue is that the listener is still present. does it matter? I can't work out how to delete it from another pushbutton and still do what I want to do.

Accepted Answer

Tommy
Tommy on 5 Jul 2020
Assuming you don't want to delete the ellipse, you could instead delete the listener within your button's callback function. You can pass the listener to that function in a number of ways, one of which is to save the listener within (or as) a property of your app. Another possibility is to directly pass the listener to your button's callback property. I hope the following helps illustrate this, even though it is simply a script and not tied to an object like in appdesigner:
f = uifigure;
ax = axes(f, 'Position', [0.1, 0.6, 0.8, 0.4]);
b = uibutton(f,...
'Position', [0.1*f.Position(3), 0.1*f.Position(4), 0.8*f.Position(3), 0.4*f.Position(4)],...
'ButtonPushedFcn', @buttonpress);
% Draw ROI
h = images.roi.Ellipse(ax, 'Center', [0.5 0.5],...
'Semiaxes', [0.3 0.3]);
% Listen for mouse movement of the ROI
l = addlistener(h, 'MovingROI', @allevents);
% Update button's callback, passing in the listener l
b.ButtonPushedFcn = {b.ButtonPushedFcn, l};
function allevents(~, evt)
evname = evt.EventName;
if strcmp(evname, 'MovingROI')
disp(['ROI moving Current Center: ' mat2str(evt.CurrentCenter)]);
disp(['ROI moving Current SemiAxes: ' mat2str(evt.CurrentSemiAxes)]);
end
end
function buttonpress(src, ~, l)
if nargin > 2 % if nargin > 3 in appdesigner, I believe
delete(l)
% src.ButtonPushedFcn = @buttonpress;
end
end
  3 Comments
Tommy
Tommy on 5 Jul 2020
Possibly easier, as you could use findobj() as you do above instead of storing the ellipse or passing it to the callback directly. I kind of figured the decision to delete the ellipse or not would depend on whether you want it to continue to show within the axes.
Jason
Jason on 6 Jul 2020
Edited: Jason on 6 Jul 2020
So I've an idea from Tommy.
when I create the listener, I assign it to an app property:
app.l=addlistener(h,'MovingROI',@app.allevents);
This then appears to allow me to delete it in other functions / button callbacks
L=app.l;
delete(L);

Sign in to comment.

More Answers (0)

Products


Release

R2019b

Community Treasure Hunt

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

Start Hunting!