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

Можно настроить размер и расположение компонентов и управлять порядком "от первого до последнего" сгруппированных компонентов путем установки определенных значений свойств. В этом разделе описывается, как использовать эти свойства для получения требуемого размещения. Это также объясняет, как использовать 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, Table, и Panel объекты имеют Position свойство, которое можно использовать, чтобы задать их местоположение и размер.

Модули измерения

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

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

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

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

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

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

  • Если вы разрабатываете кросс-платформенный UI, задайте 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® добавляет все компоненты. Таким образом, полученный UI имеет чистый внешний вид, когда он запускается.

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

Управление размещением в пользовательских интерфейсах с изменяемым размером

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

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

The SizeChangedFcn коллбэк выполняется только при следующих обстоятельствах:

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

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

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

Примечание

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

Это приложение является изменяемой версией простого приложения, заданной в Примере Простого Размещения. Этот код включает рисунок SizeChangedFcn коллбэк resizeui. The 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
The resizeui функция устанавливает местоположение и размер кнопки и осей каждый раз, когда пользователь изменяет размер окна:

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

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

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

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

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

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

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

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

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

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

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

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

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

The Children свойство Panel, ButtonGroup, или Tab объект содержит список дочерних объектов в контейнере в соответствии с порядком размещения.

Похожие темы