Свойство UIAxes YLim не может быть прослушано - PullRequest
0 голосов
/ 18 декабря 2018

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.

Ответы [ 2 ]

0 голосов
/ 22 мая 2019

Большое спасибо за это решение!У меня была реальная проблема с увеличением 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

Человек, какая это была боль.Я рад, что теперь это работает.Еще раз спасибо.

0 голосов
/ 19 декабря 2018

Мы должны присоединить слушателя к внутреннему объекту Axes, а не к самому UIAxes.Попробуйте это:

hFig = uifigure();
hAx = uiaxes(hFig);
addlistener(struct(hAx).Axes, 'YLim', 'PostSet', @(src, evnt)disp("YLim changed"));
hAx.YLim = [0 2];

Если кому-то интересно, я нашел это методом проб и ошибок.

Протестировано на R2018a и R2018b.

...