Разметка пользовательского интерфейса программно

Можно настроить размер и местоположение компонентов, и управлять порядком "от первого до последнего" сгруппированных компонентов путем установки определенных значений свойств. Эта тема объясняет, как использовать эти свойства получить размещение, которое вы хотите. Это также объясняет, как использовать коллбэк SizeChangedFcn, чтобы управлять поведением изменения размеров пользовательского интерфейса.

Размещение компонентов и калибровка

Размещение пользовательского интерфейса состоит из фигуры и одного или нескольких компонентов, которые вы помещаете в фигуре. Точное размещение и калибровка каждого компонента включают устанавливающие определенные свойства и понимающий, как внутренние и внешние границы фигуры относятся друг к другу.

Расположение и размер внешних границ и области векторной и растровой графики

Область в фигуре, которая содержит компоненты пользовательского интерфейса, называется drawable area. Область векторной и растровой графики исключает границы фигуры, строку заголовка, панель меню и панели инструментов. Можно управлять местоположением и размером области векторной и растровой графики путем установки свойства Position фигуры как четырехэлементный вектор - строка. Первые два элемента этого вектора задают местоположение. Последние два элемента задают размер. По умолчанию значения Position фигуры находятся в пикселях.

Эта команда создает фигуру и устанавливает значение Position. Левый край области векторной и растровой графики в 258 пикселях от левой стороны экрана. Его базовый край составляет 132 пикселя от нижней части экрана. Его размер 560 пикселей шириной 420 пикселей высотой:

f = figure('Position',[258 132 560 420]);

Можно запросить или изменить внешние границы фигуры при помощи свойства OuterPosition. Область, заключенная внешними границами фигуры, включает границы фигуры, строку заголовка, панель меню и панели инструментов. Как свойство Position, OuterPosition является четырьмя векторами - строками элемента:

f.OuterPosition
ans =

   250   124   576   512
Левый внешний край этой фигуры в 250 пикселях от левой стороны экрана. Его нижний внешний край составляет 124 пикселя от нижней части экрана. Область, заключенная внешними границами фигуры, 576 пикселей шириной 512 пикселей высотой.

Явным образом изменение Position или OuterPosition вызывает другое свойство измениться. Например, это - текущее значение Position f:

f.Position
ans =

   258   132   560   420
Изменение OuterPosition заставляет Position изменяться:
f.OuterPosition = [250 250 490 340];
f.Position
ans =

   258   258   474   248

Другие компоненты пользовательского интерфейса, такие как uicontrol, uitables, и uipanels имеют свойство Position, которое можно использовать, чтобы установить их местоположение и размер.

Единицы измерения

Модули по умолчанию, сопоставленные со свойством Position, зависят от компонента, который вы помещаете. Однако можно изменить свойство Units разметить пользовательский интерфейс в модулях по вашему выбору. Существует шесть различных единиц измерения, чтобы выбрать из: дюймы, сантиметры, нормированные, точки, пиксели и символы.

Всегда задавайте Units перед Position для самых предсказуемых результатов.

f = figure('Units','inches','Position',[4 3 6 5]);

Ваш выбор модулей может влиять на внешний вид и поведение изменения размеров пользовательского интерфейса:

  • Если вы хотите, чтобы компоненты пользовательского интерфейса масштабировались пропорционально с фигурой, когда пользователь изменяет размер фигуры, установите свойство Units компонентов к 'normalized'.

  • Компоненты пользовательского интерфейса не масштабируются пропорционально в фигуре, когда их свойство Units установлено в 'inches', 'centimeters', 'points', 'pixels' или 'characters'.

  • Если вы разрабатываете кросс-платформенный пользовательский интерфейс, то установленный свойство Units в 'points' или 'characters', чтобы сделать размещение сопоставимым через все платформы.

Пример простого макета

Вот код для простого приложения, содержащего оси и кнопка. Чтобы видеть, как это работает, скопируйте и вставьте этот код в редактор и запустите его.

function myui
   % Add the UI components
   hs = addcomponents;
   
   % Make figure visible after adding components
   hs.fig.Visible = 'on';
   
   function hs = addcomponents
       % add components, save handles in a struct
       hs.fig = figure('Visible','off',...
                  'Resize','off',...
                  'Tag','fig');
       hs.btn = uicontrol(hs.fig,'Position',[10 340 70 30],...
                  'String','Plot Sine',...
                  'Tag','button',...
                  'Callback',@plotsine);
       hs.ax = axes('Parent',hs.fig,...
                 'Position',[0.20 0.13 0.71 0.75],...
                 'Tag','ax');
   end

   function plotsine(hObject,event)
       theta = 0:pi/64:6*pi;
       y = sin(theta);
       plot(hs.ax,theta,y);
   end
end
Этот код выполняет следующие задачи:

  • Основная функция, myui, вызывает функцию addcomponents. Функция addcomponents возвращает структуру, hs, содержа указатели на все компоненты пользовательского интерфейса.

  • Функция addcomponents создает фигуру, оси, и кнопка, каждый с определенными значениями Position.

    • Заметьте, что свойством Resize фигуры является 'off'. Это значение отключает поддержку изменения размеров фигуры.

    • Заметьте, что свойством Visible фигуры является 'off' в функции addcomponents. Изменения значения в 'on' после addcomponents возвращаются к функции вызова. Выполнение этого задерживает отображение фигуры, пока MATLAB® не добавит все компоненты. Таким образом получившийся пользовательский интерфейс имеет чистый внешний вид, когда он запускает.

  • Графики функций plotsine синусоидальная функция в осях, когда пользователь нажимает кнопку.

Управление размещение в UIs изменяемого размера

Чтобы создать пользовательский интерфейс изменяемого размера и управлять размещением, когда пользователь изменяет размер окна, устанавливает свойство SizeChangedFcn фигуры быть указателем на функцию обратного вызова. Закодируйте функцию обратного вызова, чтобы управлять размещением, когда размер окна изменится.

Если ваш пользовательский интерфейс имеет другой контейнер, такой как uipanel или uibuttongroup, можно управлять размещением дочерних компонентов контейнера в отдельной функции обратного вызова, которую вы присваиваете свойству SizeChangedFcn.

Коллбэк SizeChangedFcn выполняется только при этих обстоятельствах:

  • Контейнер становится видимым впервые.

  • Контейнер видим, в то время как его область векторной и растровой графики изменяется.

  • Контейнер становится видимым впервые после того, как его область векторной и растровой графики изменится. Эта ситуация происходит, когда область векторной и растровой графики изменяется, в то время как контейнер невидим и становится видимым позже.

Примечание

Как правило, область векторной и растровой графики изменяет одновременно внешнее изменение границ. Однако добавление или удаление панелей меню или панелей инструментов на фигуру заставляют внешние границы изменяться, в то время как область векторной и растровой графики остается постоянной. Поэтому коллбэк SizeChangedFcn не выполняется, когда вы добавляете или удаляете панели меню или панели инструментов.

Это приложение является версией изменяемого размера простого приложения, заданного в Примере Простого макета. Этот код включает фигуру коллбэк SizeChangedFcn под названием resizeui. Функция resizeui вычисляет новые значения Position для кнопки и осей, когда пользователь изменяет размер окна. Кнопка, кажется, является стационарной, когда пользователь изменяет размер окна. Оси масштабируются с фигурой.

function myui
   % Add the UI components
   hs = addcomponents;
   
   % Make figure visible after adding components
   hs.fig.Visible = 'on';
   
   function hs = addcomponents
       % Add components, save handles in a struct
       hs.fig = figure('Visible','off',...
                  'Tag','fig',...
                  'SizeChangedFcn',@resizeui);
       hs.btn = uicontrol(hs.fig,'String',...
                  'Plot Sine',...
                  'Callback',@plotsine,...
                  'Tag','button');
       hs.ax = axes('Parent',hs.fig,...
                  'Units','pixels',...
                  'Tag','ax');
   end

   function plotsine(hObject,event)
       theta = 0:pi/64:6*pi;
       y = sin(theta);
       plot(hs.ax,theta,y);
   end

   function resizeui(hObject,event)
           
       % Get figure width and height
       figwidth = hs.fig.Position(3);
       figheight = hs.fig.Position(4);
       
       % Set button position
       bheight = 30; 
       bwidth = 70;
       bbottomedge = figheight - bheight - 50;
       bleftedge = 10;
       hs.btn.Position = [bleftedge bbottomedge bwidth bheight];
       
       % Set axes position
       axheight = .75*figheight;
       axbottomedge = max(0,figheight - axheight - 30);
       axleftedge = bleftedge + bwidth + 30;
       axwidth = max(0,figwidth - axleftedge - 50);
       hs.ax.Position = [axleftedge axbottomedge axwidth axheight];
   end
end
Функция resizeui устанавливает местоположение и размер кнопки и осей каждый раз, когда пользователь изменяет размер окна:

  • Высота кнопок, ширина и левый край остаются такими же, когда окно изменяет размер.

  • Базовый край кнопки, bbottomedge, позволяет 50 пикселей пробела между верхней частью фигуры и верхней частью кнопки.

  • Значение высоты осей, axheight, составляет 75% доступной высоты в фигуре.

  • Значение базового края осей, axbottomedge, позволяет 30 пикселей пробела между верхней частью фигуры и верхней частью осей. В этом вычислении функция max ограничивает это значение неотрицательными значениями.

  • Значение ширины осей, axwidth, позволяет 50 пикселей пробела между правой стороной осей и правым краем фигуры. В этом вычислении функция max ограничивает это значение неотрицательными значениями.

Заметьте, что весь код размещения в функции resizeui. Это - хорошая практика, чтобы поместить весь код размещения в коллбэке SizeChangedFcn, чтобы гарантировать самые точные результаты.

Кроме того, важно задержать отображение целого окна UI до окончания всех переменных, что коллбэк SizeChangedFcn использование задан. Выполнение так может препятствовать тому, чтобы коллбэк SizeChangedFcn возвратил ошибку. Чтобы задержать отображение окна, установите свойство Visible фигуры к 'off'. После того, как вы задаете все переменные, которые использует ваш коллбэк SizeChangedFcn, установите свойство Visible на 'on'.

Управление порядка размещения сгруппированных компонентов

Порядок "от первого до последнего" по умолчанию или порядок размещения, компонентов в пользовательском интерфейсе следующие:

  • Оси и другие графические объекты появляются позади других компонентов. Компоненты пользовательского интерфейса и контейнеры (uipanels, uibuttongroups, и uitabs) появляются перед ними.

  • Компоненты пользовательского интерфейса и контейнеры появляются в порядке, в котором вы создаете их. Новые компоненты появляются перед существующими компонентами.

Можно изменить порядок размещения в любое время, но существуют некоторые ограничения. Оси и другие графические объекты могут сложить в любом порядке друг относительно друга. Однако оси и другие графические объекты не могут сложить перед компонентами пользовательского интерфейса и контейнерами. Они всегда появляются позади компонентов пользовательского интерфейса и контейнеров.

Можно работать вокруг этого ограничения путем группировки графических объектов в отдельные контейнеры. Затем можно сложить те контейнеры в любом порядке. Чтобы сгруппировать графический объект в контейнер, установите его свойство Parent быть тем контейнером. Например, можно сгруппировать оси в uipanel путем установки свойства Parent осей быть uipanel.

Свойство Children uipanel, uibuttongroup, или uitab перечисляет дочерние объекты в контейнере согласно их порядку размещения.

Похожие темы