【问题标题】:Axes toolbar is not shown when axes is re-parented轴重新设置父级时不显示轴工具栏
【发布时间】:2019-06-18 08:25:25
【问题描述】:

在 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

我想知道如何使工具栏出现在选定的选项卡中。

编辑:以下代码更好地显示了问题:轴工具栏卡在第一个面板中,而轴在第二个面板中。但是,要重现这一点,请不要复制并粘贴到您的 MATLAB 命令窗口中。只有在绘制轴工具栏后轴的父级更改时才会发生这种情况。因此,我将代码分为两部分:

f = figure;
p1 = uipanel(f, 'Units', 'normalized', 'Position', [0 0 .5 1]);
p2 = uipanel(f, 'Units', 'normalized', 'Position', [.5 0 .5 1]);
ax = axes(p1);

现在更改轴的父级:

ax.Parent = p2;

结果如下:

这是我所期望的:

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

更改figureaxesaxtoolbaruipanelVisible 属性都没有帮助。此外,用新的工具栏覆盖工具栏也无济于事。

【问题讨论】:

  • toolbarfigure 的子代,而不是axes
  • @Hoki:工具栏的Parent属性指向axes,而figureChildren属性只包含tabgroup。此外,工具栏没有类似Position 属性...
  • @Hoki:也许你把它弄混了。我说的是axtoolbar 生成的相对较新的轴工具栏。
  • 我可以重现该问题。 This blog post 可能是相关的。
  • 您应该添加工具栏“卡在”它出现的第一个选项卡/面板上。如果您在显示之前切换选项卡/面板,它将(仅)处于新位置。

标签: matlab tabs matlab-figure toolbar parent


【解决方案1】:

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


经过一番调查,我注意到AxesToolbar 的几个属性在第一次显示后发生了变化,其中两个引起了我的注意——HasTrueParentNodeParent

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

我在你的类中添加了另一个属性Tabs,这就是我在构造函数中填充它的方式:

      self.Tabs(1) = uitab(tg, 'Title', 'tab1');
      self.Tabs(2) = uitab(tg, 'Title', 'tab2');
      self.Tabs(3) = uitab(tg, 'Title', 'tab3');
      self.Tabs = handle(self.Tabs);

然后,在设置(并命中)断点之后设置,我们可以看到:

K>> allchild(self.Tabs(1))
ans = 
  2×1 graphics array:

  AnnotationPane
  Axes
K>> allchild(self.Tabs(2))
ans = 
  0×0 empty GraphicsPlaceholder array.

注意到AnnotationPane?这是包含注释的图层,可能还包含工具栏。我们怎么能确定呢?我们可以将它的Visibility设置为'off',工具栏就不再出现了。

很自然,人们可能会想更改该窗格的Parent,但这会导致错误:

Error using matlab.graphics.shape.internal.AnnotationPane/setParentImpl
Cannot change parent of AnnotationPane object.

那么可以做些什么呢?如果您在每个新选项卡中创建新轴,

hFig = figure();
hTG = uitabgroup(hFig);
for iTab = 1 : 3
    hTab = uitab(hTG, 'title', "Tab" + iTab);
    hPanel = uipanel(hTab);
    hAxes(iTab) = axes(hPanel);
end

他们的工具栏将被正确创建。从那里开始,这是重新定位(轴的)子级并更新限制/视口的问题。

【讨论】:

  • 解决方法的问题在于创建的轴数。正如blog post(您在上面提到的)所示,这可能会导致性能问题。这篇博文是我想重新设置axes 的原因。
【解决方案2】:

由于我认为上述行为是一个错误,我已将其提交给 Matlab 工作人员。

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

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

【讨论】:

  • 考虑到这一点,另一种解决方案是将轴包含在 uipanel 中(无论如何这是一个好习惯)并重新设置该面板的父级。
  • 您的评论可能是一个单独的答案。
【解决方案3】:

这是我之前评论的另一个答案:

另一种解决方案是将轴放在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

【讨论】:

    猜你喜欢
    • 2020-04-03
    • 2018-09-28
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 2021-06-20
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多