Limiting mouseclick event to current Axes in App Designer

Hi, I am trying to get the mouselocation on an axes - 'app.UIAxes' (using app designer).
delete(findobj(app.UIAxes, 'Marker', '*')); %DElete previous marker
z=app.UIAxes.CurrentPoint;
x=z(1,1); y=z(1,2);
hold(app.UIAxes,'on');
plot(app.UIAxes,x,y,'b*');
hold(app.UIAxes,'off');
app.xy=[x,y]; %Save value so can access later
However, as I also have 2 other UIAxes (app.UIAxes2 & app.UIAxes3), whenever I click on any of them, it invokes the fucntion above and plots a point on the UIAxes.
How can I limit this to just the UIAxes

2 Commenti

Can you show how you are defining the event callback function? Are you using the figure's windowbuttondownfcn?
Yes Im using the figures windowbuttondownfcn.

Accedi per commentare.

 Risposta accettata

Find the pixel locations where you want the function to activate. If it’s a rectangle, then that’s easier. You’ll have four points - two x and two y. At the very beginning of your function you can write something like this:
function yourclickfunction
%cursorpos is going to be your current cursor position as (x,y)
%pos1 is your top right most point in your designated rectangle window as an (x,y)
%pos2 is is the bottom left most position in your designated rectangle window as an (x,y)
%you’ll have to determine pos1 and pos2 based on where you want your window clicks to run the function
if cursorpos(1) > pos1(1) || cursorpos(1) < pos2(1) || cursorpos(2) > pos1(2) || cursorpos(2) < pos2(2)
return
end
%run the rest of your code
end

6 Commenti

Wont this be different when running on different machines (laptop and desktop, as I do).
Yes. So you would need to assign those positions based on your current uifigure location. Use something like app.UIAxes.position or something similar (app.UIAxes.InnerPosition) to find what your positions need to be.
Is there no way to get the axes name or tag.
Jason
Jason il 18 Gen 2020
Modificato: Jason il 18 Gen 2020
I came across this.
To just record the mouse click inside a UIAxes, one can do
ax = struct(app.UIAxes).Axes; ax.ButtonDownFcn = @(h, e) click_selection(app);
...where click_selection is some callback function that one can define. Using struct() on an object might cause MATLAB to complain a bit, so if the warning annoys you, you can set warning off MATLAB:structOnObject to shut it up.
Cameron, your idea of:
function yourclickfunction
%cursorpos is going to be your current cursor position as (x,y)
%pos1 is your top right most point in your designated rectangle window as an (x,y)
%pos2 is is the bottom left most position in your designated rectangle window as an (x,y)
%you’ll have to determine pos1 and pos2 based on where you want your window clicks to run the function
if cursorpos(1) > pos1(1) || cursorpos(1) < pos2(1) || cursorpos(2) > pos1(2) || cursorpos(2) < pos2(2)
return
end
%run the rest of your code
end
doesnt seem to work. For example the x positon returned from cursorpos(1) seems to be with repect to the axes its in i.e. not global.
Needed to use this:
if x >= app.UIAxes.XLim(1) & x <= app.UIAxes.XLim(2) & y >= app.UIAxes.YLim(1) & y <= app.UIAxes.YLim(2)

Accedi per commentare.

Più risposte (1)

Cameron's idea of calculating the axes position within the figure position should work, and it is the only way with currently documented/supported matlab that I can think of too, though it would be nice if someone else could chime in.
The solution of extracting the actual axes object from the uiaxes is along the lines of what I would have suggested. But rather than create a uiaxes and get the axes from within, you can also create regular axes() inside a uifigure, and it will behave as usual (I haven't tested exhaustively, but it seems to be more or less interchangeable, except for behavior on resizing).
  1. In app designer, create a uipanel to be the container of the axes (because within appdesigner gui edtor you can't add an axes, only uiaxes), call it for example "AxesContainerPanel"
  2. In the code editor add a property called "UIAxes" (or whatever you want to call it)
  3. In the code editor add a startup function for the app
  4. In the startup function, create the axes:
app.UIAxes = axes(app.AxesContainerPanel,"ButtonDownFcn",@(o,e)AxesBDF(app,o,e))

1 Commento

So I got the idea from Cameron to work but changed the if condition to below:
z=app.UIAxes.CurrentPoint;
x=round(z(1,1)); y=round(z(1,2));
if x >= app.UIAxes.XLim(1) & x <= app.UIAxes.XLim(2) & y >= app.UIAxes.YLim(1) & y <= app.UIAxes.YLim(2)

Accedi per commentare.

Categorie

Richiesto:

il 18 Gen 2020

Commentato:

il 23 Gen 2020

Community Treasure Hunt

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

Start Hunting!

Translated by