Matlab GUI 中多Axes下的鼠标动态跟踪[windowbuttonmotionfcn 函数]

来源:互联网 发布:.wang域名能备案吗 编辑:程序博客网 时间:2024/06/05 10:51

      在GUI 中建立多个Axes用于同时显示不同的曲线或图像,并通过鼠标在各个Axes间进行交互操作是Matlab GUI编程的常见需求。下面的代码用于实现这种效果。

      代码的基本原理是运用figure控件所支持的回调函数(callback function):windowbuttonmotionfcn。其作用是检测到figure上有鼠标按下时(无论左右键)即发生调用,执行windowbuttonmotionfcn内所设计的代码。

      下面的例子建立了一个带有windowbuttonmotionfcn回调函数的实例,具体功能如下:

       当GUI中某个Axes上发生鼠标按键时,则该函数开始实时记录鼠标所在坐标,并实时显示在设定的静态文本框内。

       代码如下:

function CurPosShow(OpSet)
% Show (On/Off) the Cursor Position on the Current Axes
% OpSet = 'on' or 'off'
% the axes tag is '**n' ,and textbox' tag should be 'TXn' and 'TYn'
% Version   1.0Bata
% CopyRight WEI Zhen 2010-2014

handles=guidata(gcbo);                                    % get handles
X=get(gca,'XLim');                                             % x range of current axes
Xmin=X(1);
Xmax=X(2);
Y=get(gca,'YLim');                                              % y range of current axes
Ymin=Y(1);
Ymax=Y(2);
AxName=get(gca,'Tag');                                    % name of the current axes
hTX=findobj(gcf,'tag',['TX' AxName(end)]);        % find correspond text box x
hTY=findobj(gcf,'tag',['TY' AxName(end)]);         % find correspond text box y
%
set(gcf,'windowbuttonmotionfcn','');                  % dissable all callback in figure
set(gcf,'windowbuttonmotionfcn','CurPosShow on');   % set callback when mouse move
switch OpSet
case 'on'
   curPos = get(gca, 'CurrentPoint');
   pX=max([Xmin curPos(1,1)]);
   pX=min([Xmax pX]);
   pY=max([Ymin curPos(1,2)]);
   pY=min([Ymax pY]);
   set(hTX,'String',pX);
   set(hTY,'String',pY);
case 'off'
   set(gcf,'windowbuttonmotionfcn','');             % dissable callback
end
guidata(gcbo,handles);                              % save handles (refresh)

 

 

以上函数要求Axes的名称为‘[Axes]n’的形式,而对应的用于分别显示x,y坐标的文本框命名为 TXn 和TYn

例如,GUI上有两个Axes,分别命名为 Pic1和Pic2,那么每个对应的坐标显示框则应当命名为:

 

Pic1   对应   TX1 和 TY1

Pic2   对应   TX2 和 TY2

 

主程序中对该函数的调用非常简单,例如在Pic1上用callback向导生成ButtonDownFcn回调函数,调用时直接写为:

 

% --- Executes on mouse press over axes background.
function Pic1_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to Pic1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

       CurPosShow('on');

 

      当程序工作是,鼠标点中Pic1框后,即可发现其位置坐标反映在TX1和TY1中了。坐标值实时的在随着鼠标位置变化,无需反复点击,点击一次即可。

      继续对Pic1加载图片或曲线时,以上代码单击Pic1框会失效,无法显示坐标,并报错。这是因为imshow函数的设置问题,更改办法如下:

[FileName,PathName] = uigetfile('*.jpg','Select File');
path=fullfile(PathName,FileName);
img=imread(path);
axes(handles.Pic1);
set(gca,'NextPlot','replacechild');
hImg=imshow(img);
handles.hImg=hImg;
set(hImg,'ButtonDownFcn',{@ImgButtonDown,handles});

 

*重要步骤

1. 读入图片后,选择Pic1为当前Axes界面:     axes(handles.Pic1);

2. 设置当前Axes界面的‘NextPlot’属性为'replacechild':  set(gca,'NextPlot','replacechild');
3. 设置基于image的“buttonDown”回调函数(而不是之前属于Axes callback的Pic1_ButtonDownFcn) 

         set(hImg,'ButtonDownFcn',{@ImgButtonDown,handles});

4.在ImgButtonDown 函数中 如下书写:

function ImgButtonDown(hObject, eventdata, handles)
CurPosShow('on');

 

到此大功告成,效果如下: