Почему обратный вызов ButtonDownFcn моего объекта axes перестает работать после построения чего-либо? - PullRequest
3 голосов
/ 11 марта 2011

Я создаю набор осей на фигуре и назначаю обратный вызов для его свойства 'ButtonDownFcn', например:

HRaxes = axes('Parent', Figure, 'Position', [.05 .60 .9 .35],...
              'XLimMode', 'manual', 'ButtonDownFcn', @HR_ButtonDown);

Где функция обратного вызова определена так:

function HR_ButtonDown(hObject, eventData)
  %# Do some stuff here when the axes is clicked on...
end

Обратный вызов работает нормально, пока я не нарисую что-то на осях так:

plot(HRaxes, data.HR_X, data.HR_Y, 'b');

После чего обратный вызов больше не срабатывает, когда я нажимаю на оси. Что не так и как я могу это исправить?

Ответы [ 2 ]

2 голосов
/ 14 марта 2012

@ Дэвид Снайдер, обратите внимание, что объект image также может иметь свойство обратного вызова ButtonDownFcn.Тогда в вашем обратном вызове вы можете получить доступ к соответствующему свойству axes через свойство Parent или функцию ancestor.Например, скажем, вы хотите использовать в обратном вызове ButtonDownFcn положение пикселя и кнопку, по которой вы щелкнули.Когда вы строите изображение, используйте

imh = image(some_image);
set(imh,'ButtonDownFcn',@position_and_button);

, где вы определили свой обратный вызов где-то еще

function position_and_button(hObject,eventdata)
   Position = get( ancestor(hObject,'axes'), 'CurrentPoint' );
   Button = get( ancestor(hObject,'figure'), 'SelectionType' );
   %# do stuff with Position and Button
2 голосов
/ 11 марта 2011

Основная проблема заключается в том, что функция PLOT является высокоуровневой функцией построения графика, что означает, что она добавляет объекты на график и изменит существующие Настройки сюжета. Если вы посмотрите на свойство 'NextPlot' для объектов осей , вы увидите, что оно имеет три параметра, определяющих, как высокоуровневые функции построения графиков могут влиять на объект осей:

  • add - использовать существующие оси для рисования графических объектов.

  • replace - Сброс всех свойств осей, кроме Position, до их значений по умолчанию и удаление всех дочерних осей перед отображением графики (эквивалентно cla reset).

  • replacechildren - Удалить все дочерние объекты, но не сбрасывать свойства осей (эквивалентно cla).

Так как 'replace' является настройкой по умолчанию, дескриптор, установленный для обратного вызова 'ButtonDownFcn', обнуляется при вызове PLOT , таким образом отключая поведение при нажатии кнопки. Есть два способа избежать этого:

  • Установка свойства 'NextPlot' осей на 'add' (для добавления к существующим объектам графика) или 'replacechildren' (для замены существующих объектов на графике, но при сохранении текущих настроек свойства осей) перед позвоните по номеру PLOT .

    HRaxes = axes('Parent', Figure, 'Position', [.05 .60 .9 .35],...
                  'XLimMode', 'manual', 'ButtonDownFcn', @HR_ButtonDown,...
                  'NextPlot', 'add');
    plot(HRaxes, data.HR_X, data.HR_Y, 'b');
    
  • Использование подпрограммы нижнего уровня (например, LINE ), которая не изменяет существующие свойства графика:

    HRaxes = axes('Parent', Figure, 'Position', [.05 .60 .9 .35],...
                  'XLimMode', 'manual', 'ButtonDownFcn', @HR_ButtonDown);
    line(data.HR_X, data.HR_Y, 'Parent', HRaxes, 'Color', 'b');
    
...