Matlab 轴重设父对象时,不显示“轴”工具栏

Matlab 轴重设父对象时,不显示“轴”工具栏,matlab,tabs,matlab-figure,toolbar,parent,Matlab,Tabs,Matlab Figure,Toolbar,Parent,在MATLAB R2019a(更新2)中,当使用以下代码时,选择Tab2或Tab3时,不会显示轴工具栏 classdef test < handle properties Ax end methods function self = test() f = figure; tg = uitabgroup(f, 'SelectionChangedFcn', @self.onSelection

在MATLAB R2019a(更新2)中,当使用以下代码时,选择Tab2或Tab3时,不会显示轴工具栏

classdef test < handle
    properties
        Ax
    end
    methods
        function self = test()
            f = figure;
            tg = uitabgroup(f, 'SelectionChangedFcn', @self.onSelectionChanged);
            t1 = uitab(tg, 'Title', 'tab1');
            uitab(tg, 'Title', 'tab2');
            uitab(tg, 'Title', 'tab3');
            self.Ax = axes(t1);
        end

        function onSelectionChanged(self, ~, e)
            self.Ax.Parent = e.NewValue;

        end
    end
end
现在更改轴的父对象:

ax.Parent = p2;
结果如下:

以下是我的期望:

到目前为止,我还没有弄清楚如何触发将工具栏置于正确位置的事件


更改
图形
axtoolbar
ui面板
Visible
属性都没有帮助。此外,用新工具栏覆盖工具栏也没有帮助。

我有一些坏消息和好消息:根据我的尝试,由于MATLAB的限制,似乎无法在容器(选项卡或面板)之间移动相同的工具栏,但是,一种解决方法是可能的。下面是我如何得出这个结论的细节


在仔细研究后,我注意到,
AxesToolbar
的几个属性在第一次显示后发生了变化,其中两个引起了我的注意—
hastureparent
NodeParent

啊哈。因此,工具栏现在有了一个父级,这意味着在子级的层次结构中,选项卡应该可以看到工具栏。让我们进一步调查:

我已将另一个属性添加到类中,名为,
Tabs
,这就是我在构造函数中填充它的方式:

self.Tabs(1)=uitab(tg,'Title','tab1');
self.Tabs(2)=uitab(tg,'Title','tab2');
self.Tabs(3)=uitab(tg,'Title','tab3');
self.Tabs=句柄(self.Tabs);
然后,在设置(并点击)断点之后,我们可以看到:

K>>allchild(self.Tabs(1))
ans=
2×1图形阵列:
注释窗格
斧头
K> >所有儿童(自我标签(2))
ans=
0×0空GraphicsPlaceholder数组。
请注意,
注释窗格
?这是包含注释的图层,可能也是工具栏。我们怎么能确定呢?我们可以将其
可见性设置为
'off'
,工具栏将停止显示

因此,很自然地,人们可能会试图更改该窗格的
父项
,但这会导致错误:

使用matlab.graphics.shape.internal.AnnotationPane/setParentImpl时出错 无法更改AnnotationPane对象的父对象。

那么我们能做些什么呢?如果在每个新选项卡中创建新轴

hFig=figure();
hTG=uitabgroup(hFig);
对于iTab=1:3
hTab=uitab(hTG,‘标题’,‘标签’+iTab);
hPanel=uipanel(hTab);
hAxes(iTab)=轴(hPanel);
结束

它们的工具栏将被正确创建。从这里开始,就需要重新定位(轴的)子对象并更新限制/视口。

因为我认为上述行为是一个bug,所以我已将其提交给Matlab工作人员

为了解决这个问题,他们应该重新设置轴工具栏的父级。如果是上述测试等级:

function onSelectionChanged(self, ~, e)
    self.Ax.Parent = e.NewValue;
    set(self.Ax.Toolbar,'Parent',[],'Parent',self.Ax);
end

以下是我先前评论的另一个答案:

另一种解决方案是将轴放置在
ui面板中
(这是一种很好的做法),然后重新设置面板的父级:

classdef test < handle
    properties
        Ax
    end
    methods
        function self = test()
            f = figure;
            tg = uitabgroup(f, 'SelectionChangedFcn', @self.onSelectionChanged);
            t1 = uitab(tg, 'Title', 'tab1');
            uitab(tg, 'Title', 'tab2');
            uitab(tg, 'Title', 'tab3');
            self.Ax = axes(uipanel(t1)); % uipanel as axes parent
        end

        function onSelectionChanged(self, ~, e)
            self.Ax.Parent.Parent = e.NewValue; % re-parent the uipanel

        end
    end
end
classdef测试
工具栏是
图形
的子对象,而不是
@Hoki:工具栏的
父对象
属性指向
,而
图形
子对象属性仅包含
选项卡组
。此外,工具栏没有类似于
位置
属性的东西…@Hoki:可能是你弄错了。我说的是由
axtoolbar
生成的相对较新的axes工具栏。我可以重现这个问题。可能与此相关。您应该添加工具栏在其出现的第一个选项卡/面板上“卡住”。如果在显示之前切换选项卡/面板,它将(仅)处于新位置。解决方法的问题在于创建的轴的数量。正如(您上面提到的)所示,这可能会导致性能问题。这篇博客文章就是我想重新设置
轴的父级的原因。考虑到这一点,另一个解决方案是将轴包含在
uipanel
中(这是一个很好的做法)并重新设置该面板的父级。您的评论可以是一个单独的答案。
classdef test < handle
    properties
        Ax
    end
    methods
        function self = test()
            f = figure;
            tg = uitabgroup(f, 'SelectionChangedFcn', @self.onSelectionChanged);
            t1 = uitab(tg, 'Title', 'tab1');
            uitab(tg, 'Title', 'tab2');
            uitab(tg, 'Title', 'tab3');
            self.Ax = axes(uipanel(t1)); % uipanel as axes parent
        end

        function onSelectionChanged(self, ~, e)
            self.Ax.Parent.Parent = e.NewValue; % re-parent the uipanel

        end
    end
end