필터 지우기
필터 지우기

addlistener for drawrectangle to trigger when the rectangle is first drawn

조회 수: 31 (최근 30일)
David Aronstein
David Aronstein 2021년 6월 4일
댓글: Michal Merman 2023년 5월 31일
I want the user of my code to draw a rectangle in a plot, with:
roi = drawrectangle();
I understand how to set up a listener that gets triggered whenever the drawn rectangle gets moved/resized:
addlistener(roi,'ROIMoved', @roi_listener);
... but how do I do something similar when the rectangle is first drawn? This does not work:
addlistener(roi,'DrawingFinished', @roi_listener);
  댓글 수: 2
Adam Danz
Adam Danz 2021년 6월 8일
You'll have to set up a listener that monitors new objects added to the axes and determines if they are rectangles added by the drawrectangle function. That's why my answer does. It then removes the listener after the first rectangle is added (you can remove that section if you'd like).
Michal Merman
Michal Merman 2023년 5월 31일
Nice and elegant :)
However, this still leaves open the question how can DrawingFinished event be used?
I'm having the same issue, I'd like something to happen each time I draw a rectangle on the image - but I can't define the listener before object creation.
Would creating a custom class based on Rectangle do that?
Thanks :)

댓글을 달려면 로그인하십시오.

답변 (1개)

Adam Danz
Adam Danz 2021년 6월 4일
편집: Adam Danz 2021년 6월 9일
How to add listener that responds to the first time drawrectangle is called
For instructions on how to implement this in AppDesigner, see my comment below.
Create figure & axes
A random scatter plot is also added for demo purposes only.
fig = figure();
ax = axes(fig);
plot(ax, rand(1,20),'o')
Create listener
  • The listener will respond when objects are added to the axes but contains a condition to check for image rectangle objects.
  • The listener is stored within the axes userdata. Alternatively, you could use set/getappdata.
ax.UserData.Listener = addlistener(ax,'ChildAdded',@drawRectDetectionFcn);
Call drawrectangle
roi = drawrectangle(ax)
Listener callback function (Version 1)
The callback function performs the following tasks
  • Extract all children handles from axes.
  • Looks for "images.roi.Rectangle" objects.
  • If none are found the function returns without doing anything.
  • If a images.roi.Rectangle object is detected, the function will perform whatever action you want (fill in the code) and at the end, it will remove/disable the listener since you only want this to trigger when the first rectangle is added.
The listener can be either disabled (with the option to re-enable it again) or it can be permanently deleted. Both commands are included - you can decide which is best for your needs.
Important:, the listener will trigger when the object is added and the image rectangle object is added when drawrectangle is called before the user interactively draws the rectangle. Nevertheless, you can change properties of the rectangle such as color, for example, before the rectangle is drawn.
function drawRectDetectionFcn(ax,~)
% Evoked by listener when children are added to the axes in ax.
% Detects the presence of an images.roi.Rectangle object created
% by drawrectangle() and performs [SOME ACTION]. After the first
% rectangle obj is detected, the listener is removed.
axChil = ax.Children;
chilClass = arrayfun(@(h){class(h)},axChil);
isRect = any(strcmpi(chilClass, 'images.roi.Rectangle'));
if isRect
%
%
% DO YOUR STUFF HERE
%
%
% Remove|Disable listener after the first rectangle is added.
delete(ax.UserData.Listener) % Permanently delete listener
% ax.UserData.Listener.Enabled = false; % Disable listener
end
end
Listener callback function (Version 2)
Update: This version works with Matlab Online but not in a local installation of Matlab.
Use this version of the callback function if you need the listener to respond after the first rectangle is draw. Unlike the first version, the condition requires that the position property of the rectangle is not empty. The position property is initially empty while waiting for the user to draw the rectangle and is filled it after the drawing is complete.
function drawRectDetectionFcn(ax,~)
% Evoked by listener when children are added to the axes in ax.
% Detects the presence of a drawn images.roi.Rectangle object created
% by drawrectangle() and performs [SOME ACTION]. After the first
% rectangle obj is detected, the listener is removed.
axChil = ax.Children;
chilClass = arrayfun(@(h){class(h)},axChil);
isRect = strcmpi(chilClass, 'images.roi.Rectangle');
if any(isRect) && ~isempty(axChil(find(isRect,1)).Position)
%
%
% DO YOUR STUFF HERE
%
%
% Remove listener after first rectangle is added.
delete(ax.UserData.Listener)
%ax.UserData.Listener.Enabled = false;
end
  댓글 수: 8
David Aronstein
David Aronstein 2021년 6월 11일
I'm not sure I understand.
In my thinking of what I am trying to do, the whole problem is that calling drawrectangle without arguments (so it waits for the user to use the mouse to draw the rectangle) and then actually drawing that rectangle are separate events, and I want the program to respond immediately to the latter, not the former.
I could, instead, call drawrectangle with a 'Position' argument, so the rectangle gets drawn immediately, but then I just use a listener to trigger when it is moved. That's ok but seems a bit inelegant.
Adam Danz
Adam Danz 2021년 6월 11일
The question is, what triggers/calls drawrectangle? Is that part of the code or does the user merely enter it in the command window any time they want?

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Line Plots에 대해 자세히 알아보기

제품


릴리스

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by