Filter löschen
Filter löschen

addlistener for drawrectangle to trigger when the rectangle is first drawn

15 Ansichten (letzte 30 Tage)
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 Kommentare
Adam Danz
Adam Danz am 8 Jun. 2021
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 am 31 Mai 2023
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 :)

Melden Sie sich an, um zu kommentieren.

Antworten (1)

Adam Danz
Adam Danz am 4 Jun. 2021
Bearbeitet: Adam Danz am 9 Jun. 2021
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 Kommentare
David Aronstein
David Aronstein am 11 Jun. 2021
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 am 11 Jun. 2021
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?

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Line Plots finden Sie in Help Center und File Exchange

Produkte


Version

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by