7

MATLAB 提供了该addlistener函数。

侦听器允许我们跟踪对象属性的变化并对其采取行动。例如,我们可以创建一个非常简单的侦听器,当对象的'YLim'属性axes发生更改时,它将在命令窗口中显示一条消息:

% Example using axes
ax = axes();
addlistener(ax, 'YLim', 'PostSet', @(src, evnt)disp('YLim changed'));

尝试平移轴或放大/缩小,看看会发生什么。这工作正常。

我需要做同样的事情,但使用 anuiaxes代替。

不幸的是,看起来我们不允许这样做。尝试运行以下示例:

% Example using uiaxes
ax = uiaxes();
addlistener(ax, 'YLim', 'PostSet', @(src, evnt)disp('YLim changed'));

它抛出这个错误:

使用 matlab.ui.control.UIAxes/addlistener 时出错 添加 PostSet 侦听器时,“matlab.ui.control.UIAxes”类中的属性“YLim”未定义为 SetObservable。

我已阅读文章Listen for Changes to Property ValuesObserve Changes to Property Values,我了解到必须将属性声明为SetObservable允许被监听:

classdef PropLis < handle
   properties (SetObservable)
      ObservedProp = 1 % <-- Observable Property
   end
end

我尝试通过查看UIAxes类定义,edit matlab.ui.control.UIAxes但这是不可能的,因为它是P-file

如果'YLim'不可观察,那么我如何跟踪该属性的变化?

我在 MATLAB R2018b 中使用App Designer 。

4

2 回答 2

7

我们应该将侦听器附加到内部Axes对象,而不是UIAxes本身。尝试这个:

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

如果有人想知道,我通过反复试验发现了这一点。

在 R2018a 和 R2018b 上测试。

于 2018-12-19T16:48:14.810 回答
0

非常感谢您提供此解决方案!我在放大 UIAxes 上的 3D 数据时遇到了真正的问题。3D 轴包含 z=0 处的 .png 背景光栅图(绘制为表面)和 xyx 中无人机飞行的 3D 位置。当我放大时,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

伙计,这是多么痛苦。我很高兴它现在有效。再次感谢。

于 2019-05-22T18:47:56.200 回答