Панель инструментов осей не отображается при повторном создании осей - PullRequest
3 голосов
/ 18 июня 2019

В 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;

Вот результат: Result after re-parenting the axes

И вот что я ожидаю:

expected result

До сих пор я не понял, как вызвать событие, которое ставитпанель инструментов в правильном положении.

Не помогло ни изменение свойства Visible figure, axes, axtoolbar или uipanel.Кроме того, переопределение панели инструментов новой не помогает.

Ответы [ 3 ]

3 голосов
/ 18 июня 2019

Поскольку я считал описанное выше поведение ошибкой, я подал его сотрудникам Matlab.

Они ответили, чтобы обойти эту проблему, один раз переустановив панель инструментов Родитель осей. В случае тестового класса сверху:

function onSelectionChanged(self, ~, e)
    self.Ax.Parent = e.NewValue;
    set(self.Ax.Toolbar,'Parent',[],'Parent',self.Ax);
end
3 голосов
/ 18 июня 2019

У меня есть некоторые плохие новости и хорошие новости: на основании моих попыток кажется, что нельзя перемещать одну и ту же панель инструментов между контейнерами (вкладками или панелями) из-за ограничения MATLAB, однако возможен обходной путь. Ниже приведены подробности того, как я пришел к такому выводу.


После небольшого исследования я заметил, что некоторые свойства AxesToolbar меняются после его первого показа, два из них привлекли мое внимание - HasTrueParent и NodeParent.

Aha. Таким образом, панель инструментов теперь имеет родительский элемент, что означает, что где-то в иерархии дочерних элементов вкладка должна видеть панель инструментов. Давайте исследуем дальше:

Я добавил другое свойство в ваш класс, 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

их панели инструментов будут созданы правильно. Оттуда, это вопрос перемещения дочерних элементов (осей) и обновления лимитов / области просмотра.

1 голос
/ 18 июня 2019

Вот еще один ответ из моего предыдущего комментария:

Другое решение состоит в том, чтобы поместить оси в 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
...