how to create mouse movement event on UIAxes in APP Designer to catch cursor location on the axes?

조회 수: 105 (최근 30일)
I have a UIAxes created in App designer. now I want to show cursor's x y location when mouse is moving on the axe, not click.

채택된 답변

Adam Danz
Adam Danz 2021년 3월 18일
편집: Adam Danz 2021년 3월 22일
Here are 2 methods to capture mouse coordinates within the axes of a figure.
In these demos the coordinates of the cursor's current point on the axes will appear in the text box. When the mouse leaves the axes, the textbox will clear.
Be aware of the limit in precision of CurrentPoint within axes (see this explanation). For example, you may not be able to select an exact coordinate such as (0,0).
Method 1: Use a pointer manager (requires Image Processing Toolbox)
Instead of using the WindowButtonMotionFcn which requires you to detect when the mouse enters the axes, use a pointer manager assigned to the axes that returns the axes' current point when the mouse is over the axes. This is more efficient than the WindowButtonMotionFcn.
Add this to you app's startup function.
Key components
% Code that executes after component creation
function startupFcn(app)
pm.enterFcn = [];
pm.exitFcn = @(~,~) set(app.CurrentPositionEditField, 'Value', '');
pm.traverseFcn = @(~,~) set(app.CurrentPositionEditField, 'Value',...
sprintf('%.2f, %.2f', app.UIAxes.CurrentPoint(1,1:2)));
iptSetPointerBehavior(app.UIAxes, pm)
iptPointerManager(app.UIFigure,'enable');
set(app.UIFigure,'WindowButtonMotionFcn',@(~,~)NaN) %dummy fcn so that currentpoint is continually updated
end
Method 2: Assign a WindowButtonMotion to the figure
As Mohammad Sami suggested, the WindowButtonMotion function is assigned in AppDesigner > Designer View > in the Component Browser select the figure handle > callback > WindowButtonMotionFcn.
Key components
  • app.UIAxes - handle to the app's axes
  • app.UIFigure - handle to the app's figure
  • app.CurrentPositionEditField - handle to the text box
  • UIFigureWindowButtonMotion() - See instructions above.
% Window button motion function: UIFigure
function UIFigureWindowButtonMotion(app, event)
% Determine if mouse is within uiaxes
cp = app.UIFigure.CurrentPoint;
isInAxes = cp(1) >= app.UIAxes.Position(1) && ...
cp(1) <= sum(app.UIAxes.Position([1,3])) && ...
cp(2) >= app.UIAxes.Position(2) && ...
cp(2) <= sum(app.UIAxes.Position([2,4]));
if isInAxes
% Update displayed coordinates
set(app.CurrentPositionEditField, 'Value',...
sprintf('%.2f, %.2f', app.UIAxes.CurrentPoint(1,1:2)))
else
% Clear displayed coordinates
set(app.CurrentPositionEditField, 'Value', '')
end
end
  댓글 수: 30
Adam Danz
Adam Danz 2021년 7월 26일
Hi Franck, I tested your attached app. It throws a warning when you enter/leave the patch area.
Warning: Error occurred while executing the listener callback for event WindowMouseMotion defined for class matlab.ui.Figure:
Unrecognized method, property, or field 'TextArea' for class 'showCurrentPointApp_test01'.
Error in showCurrentPointApp_test01/startupFcn/cursorPositionFeedback (line 46)
app.TextArea.Value = txt;
Error in showCurrentPointApp_test01>@(~,~)cursorPositionFeedback(app,region1,'in') (line 25)
pm.enterFcn = @(~,~) cursorPositionFeedback(app, region1, 'in');
Error in iptPointerManager>callIfNotEmpty (line 164)
fcn(varargin{:});
Error in iptPointerManager>createPointerManager/updatePointer (line 350)
callIfNotEmpty(overMe.PointerBehavior.enterFcn, hFigure, currentPoint);
The warning indicates the problem "Unrecognized method, property, or field 'TextArea' "
Your TextArea is named TextAreaEditField. After fixing that, problem solved.

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

추가 답변 (1개)

Mohammad Sami
Mohammad Sami 2021년 3월 17일
You can set the callback WindowButtonMotionFcn on the app.UIFigure.
To add the callback in AppDesigner see the picture below. Select app.UIFigure in component browser/
Click callbacks and scroll to find WindowButtonMotionFcn. Click the dropdown and select add.
% Window button motion function: UIFigure
function UIFigureWindowButtonMotion(app, event)
% you can leave this empty if you don't want live update
disp(app.UIAxes.CurrentPoint); % you will have to differentiate if this actually inside uiaxes.
disp(app.UIFigure.CurrentPoint);
end
  댓글 수: 5
Mohammad Sami
Mohammad Sami 2021년 3월 18일
From what I can see in the data
% If the cursor is completely outside the UIAxes
Columns 1 through 2
-1.26587301587302 1.1579754601227
-1.26587301587302 1.1579754601227
Column 3
9.16025403784439
0.5
% If the cursor is inside any of the UIAxes
Columns 1 through 2
1.92297485039581 -0.157787889333874
1.92297485039581 -0.157787889333874
Column 3
1
0
Based on this I suggest you do two things. This likely may only work for 2D UIAxes.
u1 = app.UIAxes.CurrentPoint;
if isequal(u1(:,3),[1;0])
x1 = u1(1,1);
y1 = u1(1,2);
x1lim = app.UIAxes.XLim;
y1lim = app.UIAxes.YLim;
insideAxes = x1 >= x1lim(1) & x1 <= x1lim(2) & y1 >= y1lim(1) & y1 <= y1lim(2);
else
insideAxes = false;
end
u2 = app.UIAxes2.CurrentPoint;
if isequal(u2(:,3),[1;0])
x2 = u2(1,1);
y2 = u2(1,2);
x2lim = app.UIAxes2.XLim;
y2lim = app.UIAxes2.YLim;
insideAxes2 = x2 >= x2lim(1) & x2 <= x2lim(2) & y2 >= y2lim(1) & y2 <= y2lim(2);
else
insideAxes2 = false;
end
Mohammad Sami
Mohammad Sami 2021년 3월 18일
You can convert this into a function.
function [inside,point] = insideAxes(app,Axes)
u = Axes.CurrentPoint;
if isequal(u(:,3),[1;0])
x = u(1,1);
y = u(1,2);
xlim = Axes.XLim;
ylim = Axes.YLim;
inside = x >= xlim(1) & x <= xlim(2) & y >= ylim(1) & y <= ylim(2);
point = u(1,1:2);
else
inside = false;
point = [NaN, NaN];
end
end
function someotherfunc(app)
[inside1,point1] = app.insideAxes(app.UIAxes);
[inside2,point2] = app.insideAxes(app.UIAxes2);
end

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

카테고리

Help CenterFile Exchange에서 Develop Apps Using App Designer에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by