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

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

Начиная с R2020b, вместо скрипта или функции можно создать реализацию класса для компонентов пользовательского интерфейса путем определения подкласса ComponentContainer базовый класс. Создание класса имеет следующие преимущества:

  • Простая индивидуальная настройка - когда пользователи хотят настроить аспект вашего компонента пользовательского интерфейса, они могут задать свойство, а не изменять и перезапускать ваш код. Пользователи могут изменять свойства в командной строке или просматривать их в Property Inspector.

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

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

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

В первой линии класса компонента пользовательского интерфейса задайте matlab.ui.componentcontainer.ComponentContainer класс как суперкласс. Например, первая линия класса под названием ColorSelector выглядит следующим образом:

classdef ColorSelector < matlab.ui.componentcontainer.ComponentContainer

В дополнение к указанию суперкласса включите следующие компоненты в определение класса. Некоторые компоненты требуются, в то время как другие являются рекомендуемыми или необязательными.

КомпонентОписание

Блок общественной собственности
рекомендуется

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

Блок частной собственности
рекомендуется

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

В этом блоке установите следующие значения атрибутов:

  • Access = private

  • Transient

  • NonCopyable

Блок событий
(необязательно)

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

В этом блоке установите следующие значения атрибутов:

  • HasCallbackProperty

  • NotifyAccess = protected

Когда вы устанавливаете HasCallbackProperty атрибут, MATLAB® создает общественную собственность для каждого события в блоке. Общественная собственность сохраняет предоставленный пользователем коллбэк, чтобы выполнить его при возникновении события.

setup метод
(обязательно)

Этот метод устанавливает начальное состояние компонента UI. Он выполняется один раз, когда MATLAB создает объект.

Определите этот метод в защищенном блоке, чтобы его мог выполнять только ваш класс.

update метод
(обязательно)

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

  • Во время следующего drawnow выполнение после изменения пользователем одного или нескольких значений свойств

  • Когда изменяется аспект графического окружения пользователя (такой как размер)

Определите этот метод в том же защищенном блоке, что и setup способ.

Метод конструктора

Вы не должны писать метод конструктора для вашего класса, потому что он наследует метод от ComponentContainer базовый класс. Унаследованный конструктор принимает необязательные входные параметры: родительский контейнер и любое количество аргументов пары "имя-значение" для настройки свойств в компоненте пользовательского интерфейса. Для примера, если вы задаете класс, называемый ColorSelector который имеет общественную собственность Value и ValueChangedFcn, можно создать образец своего класса с помощью этого кода:

f = uifigure; 
c = ColorSelector(f,'Value',[1 1 0],'ValueChangedFcn',@(o,e)disp('Changed'))

Если вы хотите предоставить конструктор, который имеет другой синтаксис или другое поведение, можно задать пользовательский метод конструктора. Пример пользовательского конструктора см. в разделе Запись конструкторов для классов График.

Блоки публичных и частных свойств

Разделите свойства вашего класса как минимум между двумя блоками:

  • Общедоступный блок для хранения компонентов пользовательского интерфейса

  • Частный блок для хранения деталей реализации, которые вы хотите скрыть

Свойства, которые находятся в общем блоке, сохраняют входные значения, предоставленные пользователем. Для примера компонент пользовательского интерфейса, который позволяет пользователю выбрать значение цвета, может хранить значение цвета в общественной собственности. Поскольку аргументы пары "имя-значение" свойства являются необязательными входами в неявный метод конструктора, рекомендуемый подход состоит в том, чтобы инициализировать общественную собственность до значений по умолчанию.

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

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

properties
   Value {validateattributes(Value, ...
        {'double'},{'<=',1,'>=',0,'size',[1 3]})} = [1 0 0];   
end

properties(Access = private,Transient,NonCopyable)
   Grid matlab.ui.container.GridLayout 
   Button matlab.ui.control.Button 
   EditField matlab.ui.control.EditField
end   

Блок событий

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

Создайте общественную собственность для каждого события в блоке путем определения HasCallbackProperty атрибут. Общественная собственность сохраняет предоставленный пользователем коллбэк, чтобы выполнить его при возникновении события. Имя общественной собственности - это имя события, к которому добавлены буквы Fcn. Например, компонент пользовательского интерфейса, который позволяет пользователю выбрать значение цвета, может задать событие ValueChanged, который генерирует соответствующую общественную собственность ValueChangedFcn. Используйте notify метод для запуска события и выполнения коллбэка в свойстве.

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

events (HasCallbackProperty, NotifyAccess = protected) 
   ValueChanged 
end 
Когда пользователь выбирает значение цвета, вызывайте notify метод для запуска ValueChanged событие и выполните коллбэк в ValueChangedFcn свойство.
function getColorFromUser(obj)
    c = uisetcolor(obj.Value);
    if (isscalar(c) && (c == 0))
        return;
    end
    
    % Update the Value property
    oldValue = obj.Value;
    obj.Value = c;

    % Execute user callbacks and listeners
    notify(obj,'ValueChanged');
end
Когда пользователь создает образец компонента пользовательского интерфейса, он может задать коллбэк, который должен выполняться, когда значение цвета изменяется с помощью сгенерированной общественной собственности.
f = uifigure; 
c = ColorSelector(f,'ValueChangedFcn',@(o,e)disp('Changed'))
Дополнительные сведения об указании коллбэков на свойства см. в разделе Запись коллбэков для приложений, созданных программно.

Метод Setup

Задайте setup метод для вашего класса. A setup метод выполняется один раз, когда MATLAB создает объект компонента пользовательского интерфейса. Любые значения свойств, переданные в качестве аргументов пары "имя-значение" в метод конструктора, назначаются после выполнения этого метода.

Используйте setup метод для:

  • Создайте графические объекты и объекты пользовательского интерфейса, входящие в состав компонента.

  • Сохраните объекты как частная собственность на объекте компонента.

  • Раскладывайте и конфигурируйте объекты.

  • Подключите объекты, чтобы сделать что-то полезное в компоненте.

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

Большинство функций создания объектов пользовательского интерфейса имеют необязательный входной параметр для определения родительского элемента. При вызове этих функций из метода класса необходимо задать целевой родительский элемент. The setup метод принимает один аргумент, который представляет образец настраиваемого объекта компонента пользовательского интерфейса. Используйте этот аргумент, чтобы задать компонент UI в качестве целевого родительского элемента при вызове функции создания объектов из setup способ.

Например, рассмотрим компонент UI, который имеет следующие свойства:

  • Одна общественная собственность называется Value

  • Три частной собственности, называемые Grid, Button, и EditField

The setup метод вызывает uigridlayout, uieditfield, и uibutton функции для создания базового графического объекта для каждой частной собственности, задающие образец компонента UI (obj) как целевой родительский элемент.

function setup(obj) 
    % Create grid layout to manage building blocks 
    obj.Grid = uigridlayout(obj,[1 2],'ColumnWidth',{'1x',22},... 
       'RowHeight',{'fit'},'ColumnSpacing',2,'Padding',2); 

    % Create edit field for entering color value
    obj.EditField = uieditfield(obj.Grid,'Editable',false,... 
       'HorizontalAlignment','center'); 

    % Create button to confirm color change
    obj.Button = uibutton(obj.Grid,'Text',char(9998), ... 
       'ButtonPushedFcn',@(o,e) obj.getColorFromUser()); 
end 

Метод обновления

Задайте update метод для вашего класса. Этот метод выполняется, когда вашему объекту компонента пользовательского интерфейса необходимо изменить его внешний вид в ответ на изменение значений.

Используйте update метод для перенастройки базовых графических объектов в компоненте пользовательского интерфейса на основе новых значений общественной собственности. Как правило, этот метод не определяет, какой из общественной собственности изменился. Он перенастраивает все аспекты базовых графических объектов, которые зависят от общественной собственности.

Например, рассмотрим компонент UI, который имеет следующие свойства:

  • Одна общественная собственность называется Value

  • Три частной собственности, называемые Grid, Button, и EditField

update метод обновляет BackgroundColor от EditField и Button объекты с цветом, сохраненным в Value. update метод также обновляет EditField объект с числовым представлением цвета. Однако таким образом Value изменяется, изменение становится одинаково заметным везде.

function update(obj)      
    % Update edit field and button colors 
    set([obj.EditField obj.Button],'BackgroundColor',obj.Value, ... 
       'FontColor',obj.getContrastingColor(obj.Value));  

    % Update edit field display text 
    obj.EditField.Value = num2str(obj.Value,'%0.2g ');            

end

Может возникнуть задержка между изменением значений свойств и наблюдением результатов этих изменений. The update метод запускается впервые после setup метод запускается, а затем запускается каждый раз drawnow выполняет. drawnow функция выполняется автоматически периодически, на основе состояния графического окружения в сеансе работы с MATLAB пользователя. Это периодическое выполнение может привести к потенциальной задержке.

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

В этом примере показано, как создать компонент пользовательского интерфейса для выбора цвета, используя код, обсуждаемый в других разделах этой страницы. Создайте файл определения класса с именем ColorSelectorComponent.m в папке, расположенной в пути MATLAB. Определите класс путем выполнения следующих шагов.

ШагРеализация

Вывод из ComponentContainer базовый класс.

classdef ColorSelector < matlab.ui.componentcontainer.ComponentContainer

Задайте общественную собственность.

    properties
        Value {validateattributes(Value, ...
            {'double'},{'<=',1,'>=',0,'size',[1 3]})} = [1 0 0]; 
    end

Определение публичных мероприятий.

    events (HasCallbackProperty, NotifyAccess = protected) 
        ValueChanged % ValueChangedFcn will be the generated callback property 
    end

Задайте частную собственность.

    properties (Access = private, Transient, NonCopyable) 
        Grid matlab.ui.container.GridLayout 
        Button matlab.ui.control.Button 
        EditField matlab.ui.control.EditField 
    end

Реализуйте setup способ. В этом случае вызовите uigridlayout, uieditfield, и uibutton функции для создания GridLayout, EditField, и Button объекты. Храните эти объекты в соответствующих частной собственности.

Задайте getColorFromUser метод как ButtonPushedFcn коллбэк, который вызывается при нажатии кнопки.

    methods (Access = protected) 
        function setup(obj) 
            % Grid layout to manage building blocks 
            obj.Grid = uigridlayout(obj,[1,2],'ColumnWidth',{'1x',22}, ... 
                'RowHeight',{'fit'},'ColumnSpacing',2,'Padding',2);              

            % Edit field for value display and button to launch uisetcolor 
            obj.EditField = uieditfield(obj.Grid,'Editable',false, ... 
                'HorizontalAlignment','center'); 
            obj.Button = uibutton(obj.Grid,'Text',char(9998), ... 
                'ButtonPushedFcn',@(o,e) obj.getColorFromUser()); 

        end 

Реализуйте update способ. В этом случае обновляйте цвет фона базовых объектов и текст в поле редактирования, чтобы отобразить значение цвета.

        function update(obj)     
            % Update edit field and button colors 
            set([obj.EditField obj.Button],'BackgroundColor',obj.Value, ... 
                'FontColor',obj.getContrastingColor(obj.Value));  

            % Update the display text 
            obj.EditField.Value = num2str(obj.Value,'%0.2g ');            
        end 
    end 

Проводите коллбэки и другие части вместе с помощью частных методов.

Когда getColorFromUser метод запускается нажатием кнопки, вызовите uisetcolor функцию, чтобы открыть палитру цветов и затем вызвать notify функция для выполнения коллбэка пользователя и функций прослушивателя.

Когда getContrastingColor метод вызывается update метод, вычислите, является ли черный или белый текст более читаемым на новом цвете фона.

    methods (Access = private) 
        function getColorFromUser(obj) 
            c = uisetcolor(obj.Value); 
            if (isscalar(c) && (c == 0)) 
                return; 
            end 
            
            % Update the Value property 
            obj.Value = c;              

            % Execute user callbacks and listeners
            notify(obj,'ValueChanged'); 
        end         
        function contrastColor = getContrastingColor(~,color) 
            % Calculate opposite color 
            c = color * 255; 
            contrastColor = [1 1 1]; 
            if (c(1)*.299 + c(2)*.587 + c(3)*.114) > 186 
                contrastColor = [0 0 0]; 
            end 
        end 
    end 
end

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

h = ColorSelector('Value', [1 1 0]); 
h.ValueChangedFcn = @(o,e) disp('Color changed');

Instance of the color selector UI component displaying the color yellow.

Нажмите кнопку и выберите цвет с помощью палитры цветов. Компонент изменяет внешний вид, и MATLAB отображает слова Color changed в Командном окне.

Instance of the color selector UI component displaying the color blue.

См. также

Классы

Функции

Похожие темы