Как я могу реализовать устаревшую функциональность полного указателя перекрестия в MATLAB?

Я пытаюсь заменить указатель на графике полным перекрестием (то есть набором из двух перпендикулярных линий, которые тянутся к краям графика по вертикали и горизонтали и следуют за курсором мыши). Несколько лет назад я смог сделать это с помощью этой строки кода:

set(gcf,'Pointer','fullcross')

Однако, когда я пытаюсь запустить эту строку сейчас, я получаю следующее сообщение:

Warning: Full crosshair pointer is no longer supported. A crosshair pointer will be used instead.

Я бы очень хотел найти альтернативный способ реализовать эту функциональность, но пока не смог. Я столкнулся со следующей функцией: MYGINPUT, но, похоже, выполнить то, что я ищу. У кого-нибудь есть предложения?


person Alarik    schedule 15.11.2017    source источник


Ответы (1)


На самом деле вы можете сделать это, добавив 'WindowButtonMotionFcn'< /a> к вашей фигуре (при условии, что больше ничего ее не использует), которая будет отображать линии перекрестия на ваших осях, когда ваша мышь находится над ней. Вот функция, которая создает такую ​​функциональность для всех осей на фигуре:

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', []);
person gnovice    schedule 15.11.2017
comment
Прежде всего, спасибо, что нашли время ответить! Я довольно потерян относительно того, как на самом деле реализовать это. Пожалуйста, посмотрите редактирование, которое я внес в свой исходный вопрос для кода, который я пробовал (редактирование должно появиться через несколько минут). Спасибо еще раз! - person Alarik; 16.11.2017
comment
спасибо gnovice! Я заставил ваш код работать, изменив две строки (см. РЕДАКТИРОВАТЬ 2 в моем исходном сообщении). В качестве продолжения, если у меня есть несколько подзаголовков, можно ли заставить эту работу работать более чем на одном подзаголовке одновременно? Первоначальная реализация set(gcf,'Pointer','fullcross') работала бы на всей фигуре (а не на отдельных графиках). Есть ли способ сделать что-то подобное с этим? - person Alarik; 16.11.2017
comment
@Alarik: я не уверен, почему вы получили эту первую ошибку. Функция line должна позволить вам передать нужные родительские оси в качестве первого аргумента. Вы можете попробовать ... = line(..., ..., 'Parent', hAxes); и посмотреть, сработает ли это. Чтобы заставить вышеприведенное работать для всех осей на рисунке, потребуется немного повозиться, но я добавлю обновление, когда смогу. - person gnovice; 16.11.2017
comment
@Alarik: новая версия выше добавит полную функциональность перекрестия ко всем осям на рисунке, а также учтет изменения в пределах осей. - person gnovice; 16.11.2017
comment
Спасибо, это отлично работает! Я не уверен, стоит ли мне начинать новую ветку вопросов по этому поводу, но возможно ли, чтобы перекрестие появлялось постоянно? Другими словами, пока мой курсор находится в любом месте в пределах окна рисунка, появляются перпендикулярные линии и тянутся к краям самого рисунка, а не к какому-либо отдельному графику. Если это требует нового вопроса, пожалуйста, дайте мне знать (я не хочу нарушать правила или что-то в этом роде, задавая слишком много похожих вопросов). - person Alarik; 16.11.2017
comment
@Alarik: Я думаю, что это, возможно, требует нового вопроса. Это потребует немного другого подхода и будет зависеть от нескольких вещей... Вы хотите, чтобы перекрестие оставалось видимым, когда курсор находится за пределами фигуры? Если да, хотите ли вы, чтобы перекрестие продолжало обновлять положение, когда курсор перемещается за пределы фигуры? - person gnovice; 16.11.2017