Свойство UIAxes YLim не может быть прослушано
MATLAB обеспечивает addlistener
функция.
Слушатели позволяют нам отслеживать изменения свойств объекта и воздействовать на них. Например, мы можем создать очень простой слушатель, который будет отображать сообщение в командном окне, когда 'YLim'
собственность axes
объект изменен:
% Example using axes
ax = axes();
addlistener(ax, 'YLim', 'PostSet', @(src, evnt)disp('YLim changed'));
Попробуйте панорамировать оси или увеличить / уменьшить изображение и посмотреть, что произойдет. Это отлично работает.
Мне нужно сделать то же самое, но с помощью uiaxes
вместо.
К сожалению, похоже, что нам запрещено это делать. Попробуйте запустить следующий пример:
% Example using uiaxes
ax = uiaxes();
addlistener(ax, 'YLim', 'PostSet', @(src, evnt)disp('YLim changed'));
Выдает эту ошибку:
Ошибка при использовании matlab.ui.control.UIAxes/addlistener При добавлении слушателя PostSet свойство 'YLim' в классе 'matlab.ui.control.UIAxes' не определено как SetObservable.
Я прочитал статьи Прослушайте изменения значений свойств и наблюдайте за изменениями значений свойств, и я узнал, что свойство должно быть объявлено как SetObservable
чтобы быть услышанным:
classdef PropLis < handle
properties (SetObservable)
ObservedProp = 1 % <-- Observable Property
end
end
Я пытался взглянуть на UIAxes
определение класса через edit matlab.ui.control.UIAxes
но это невозможно, потому что это P-файл.
Если 'YLim'
тогда не наблюдается, как я могу отслеживать изменения в этом свойстве?
Я использую App Designer в MATLAB R2018b.
1 ответ
Мы должны прикрепить слушателя к внутреннему Axes
объект, а не UIAxes
сам. Попробуй это:
hFig = uifigure();
hAx = uiaxes(hFig);
addlistener(struct(hAx).Axes, 'YLim', 'PostSet', @(src, evnt)disp("YLim changed"));
hAx.YLim = [0 2];
Если кому-то интересно, я нашел это методом проб и ошибок.
Протестировано на R2018a и R2018b.
Большое спасибо за это решение! У меня была реальная проблема с увеличением 3D-данных на UIAxes. Трехмерные оси содержали фоновую растровую карту.png при z=0 ( нанесенную на поверхность) и трехмерную позицию полета БПЛА в xyx. Когда я увеличивал масштаб, z также увеличивал масштаб, и новые пределы z исключали карту, которую я всегда хотел отобразить. Что было странно?
app.UIAxes2.Interactions = [zoomInteraction('Dimensions','xy')];
устранит проблему при масштабировании с помощью колеса прокрутки на моей мыши, но если я выберу кнопку панели масштабирования (щелкнув для увеличения), она все равно будет увеличивать z. Действительно расстраивает.
Чтобы обойти это, я использовал ваш пример, но добавил слушателя к 'ZLim' и сделал функцию обратного вызова, которая бы смотрела на все элементы графика, и сбросил ZLim для включения всех данных при каждом изменении ZLim.
warning('off','MATLAB:structOnObject');
addlistener(struct(app.UIAxes2).Axes, 'ZLim', 'PostSet', @(src,evnt)mapholdaltlims(app,app.UIAxes2));
function [inclusivezlim] = mapholdaltlims(app,ax)
objwithz = findobj(app.UIAxes2.Children,'-property','ZData');
currmin_z = 0;
currmax_z = 0;
for i = 1:length(objwithz)
currmin_z = min([min(min(objwithz(i).ZData)), currmin_z]);%Need double mins because data could be 2d surface
currmax_z = max([max(max(objwithz(i).ZData)), currmax_z]);
end
inclusivezlim = [currmin_z currmax_z];
ax.ZLim = inclusivezlim;
%disp('Updated the limits')
end
Чувак, какая это была боль. Я рад, что теперь это работает. Еще раз спасибо.