Как я могу реализовать устаревшую функциональность указателя полного перекрестия в MATLAB?
Я пытаюсь заменить указатель на графике полным перекрестием (то есть набором из 2 перпендикулярных линий, которые тянутся к краям графика вертикально и горизонтально и следуют за курсором мыши). Много лет назад я смог сделать это с помощью следующей строки кода:
set(gcf,'Pointer','fullcross')
Однако, когда я пытаюсь запустить эту строку сейчас, я получаю следующее сообщение:
Warning: Full crosshair pointer is no longer supported. A crosshair pointer will be used instead.
Я бы очень хотел найти альтернативный способ реализации этой функциональности, но не смог этого сделать. далеко. Я столкнулся со следующей функцией: MYGINPUT , но она, похоже, не выполняет то, что я ищу. У кого-нибудь есть предложения?
1 ответ:
Вы действительно можете сделать это, добавив
'WindowButtonMotionFcn'
к вашей фигуре (предполагая, что ничто другое не использует ее), которая будет отображать линии перекрестия в ваших осях, когда ваша мышь находится над ней. Вот функция, которая создает такую функциональность для всех осей на рисунке:function full_crosshair(hFigure) % Find axes children: hAxes = findall(hFigure, 'Type', 'axes'); % Get all axes limits: xLimits = get(hAxes, 'XLim'); xLimits = vertcat(xLimits{:}); yLimits = get(hAxes, 'YLim'); yLimits = vertcat(yLimits{:}); % Create lines (not displayed yet due to NaNs) and listeners: for iAxes = 1:numel(hAxes) hHoriz(iAxes) = line(xLimits(iAxes, :), nan(1, 2), 'Parent', hAxes(iAxes)); hVert(iAxes) = line(nan(1, 2), yLimits(iAxes, :), 'Parent', hAxes(iAxes)); listenObj(iAxes) = addlistener(hAxes(iAxes), {'XLim', 'YLim'}, ... 'PostSet', @(~, ~) update_limits(iAxes)); end % Set callback on the axes parent to the nested function below: set(hFigure, 'WindowButtonMotionFcn', @show_lines); function update_limits(axesIndex) xLimits(axesIndex, :) = get(hAxes(axesIndex), 'XLim'); yLimits(axesIndex, :) = get(hAxes(axesIndex), 'YLim'); set(hHoriz(axesIndex), 'XData', xLimits(axesIndex, :)); set(hVert(axesIndex), 'YData', yLimits(axesIndex, :)); end function show_lines(~, ~) % Get current cursor positions in axes: cursorPos = get(hAxes, 'CurrentPoint'); cursorPos = vertcat(cursorPos{:}); cursorPos = cursorPos(1:2:end, 1:2); % Determine if the cursor is within an axes: inAxes = (cursorPos(:, 1) >= xLimits(:, 1)) & ... (cursorPos(:, 1) <= xLimits(:, 2)) & ... (cursorPos(:, 2) >= yLimits(:, 1)) & ... (cursorPos(:, 2) <= yLimits(:, 2)); % Update lines and cursor: if any(inAxes) % Cursor within an axes set(hFigure, 'Pointer', 'custom', 'PointerShapeCData', nan(16)); set(hHoriz(inAxes), {'YData'}, num2cell(cursorPos(inAxes, 2)*[1 1], 2)); set(hVert(inAxes), {'XData'}, num2cell(cursorPos(inAxes, 1)*[1 1], 2)); set(hHoriz(~inAxes), 'YData', nan(1, 2)); set(hVert(~inAxes), 'XData', nan(1, 2)); else % Cursor outside axes set(hFigure, 'Pointer', 'arrow'); set(hHoriz, 'YData', nan(1, 2)); set(hVert, 'XData', nan(1, 2)); end end end
Если вы сделаете следующее:
full_crosshair(gcf);
Затем, когда вы наведете курсор на каждую ось на вашем рисунке, курсор исчезнет, и вы увидите, как появляются две линии и отслеживают положение мыши. Если любая из осей ограничивает изменение, то слушатели событий в приведенном выше коде обнаружат и учтут его. Если оси добавлены или удалены из рисунка, вам нужно будет снова вызвать
full_crosshair
, чтобы обновить'WindowButtonMotionFcn'
соответственно.Наконец, вы можете отключить его, просто очистив
'WindowButtonMotionFcn'
:set(gcf, 'WindowButtonMotionFcn', []);