При разработке пользовательского компонента пользовательского интерфейса в качестве подкласса ComponentContainer базовый класс, вы можете использовать определенные методы, чтобы сделать код более надежным, эффективным и удобным для пользователя. Эти методы сосредоточены на определении свойств класса и управлении ими. Используйте все, что полезно для типа компонента, который вы хотите создать, и пользовательского интерфейса, который вы хотите предоставить.
Инициализировать значения свойств (Initialize Property Values) - задает состояние по умолчанию компонента пользовательского интерфейса, если пользователи вызывают неявный конструктор без каких-либо входных аргументов.
Проверить значения свойств (Validate Property Values) - перед их использованием убедитесь, что значения действительны.
Настроить отображение свойств - предоставление настраиваемого списка свойств в окне команд, когда пользователь ссылается на объект компонента пользовательского интерфейса без точки с запятой.
Оптимизация метода обновления - повышение производительности update метод, когда в вычислениях используется только подмножество свойств.
Пример этих методов см. в разделе Пример: Оптимизированная полиномиальная посадка компонента пользовательского интерфейса с пользовательским отображением свойств.
Кроме того, при необходимости использования пользовательского интерфейса в App Designer или предоставления общего доступа к компоненту пользователям, разрабатывающим приложения в App Designer, необходимо учитывать некоторые соображения и ограничения. Эти соображения перечислены на отдельной странице в разделе Настройка настраиваемых компонентов пользовательского интерфейса для App Designer.
Назначьте значения по умолчанию для всех общих свойств класса. Это позволяет MATLAB создавать допустимый компонент пользовательского интерфейса, даже если пользователь пропускает некоторые аргументы «имя-значение» при вызове метода конструктора.
Для компонентов пользовательского интерфейса, которые содержат диаграмму и имеют свойства, хранящие данные координат, задайте начальные значения NaN значения или пустые массивы, так что диаграмма по умолчанию пуста, если пользователь не указывает координаты.
Прежде чем код будет использовать значения свойств, убедитесь, что они имеют правильный размер и класс. Например, этот блок свойств проверяет размер и класс трех свойств.
properties LineColor {validateattributes(LineColor,{'double'}, ... {'<=',1,'>=',0,'size',[1 3]})} = [1 0 0] XData (1,:) double = NaN YData (1,:) double = NaN end
LineColor должен быть массивом класса 1 на 3 double, где каждое значение находится в диапазоне [0,1]. Оба XData и YData должны быть векторами строк класса double.
Можно также проверить свойства, которые хранят нижележащие объекты компонента в компоненте пользовательского интерфейса. Для этого необходимо знать правильное имя класса для каждого объекта. Чтобы определить имя класса объекта, вызовите соответствующую функцию компонента пользовательского интерфейса в командной строке, а затем вызовите class для получения имени класса. Например, если планируется создать раскрывающийся компонент в setup метод, вызовите uidropdown в командной строке с выходным аргументом. Затем передайте выходной сигнал в class для получения имени класса.
dd = uidropdown; class(d)
ans =
'matlab.ui.control.DropDown'Используйте выходные данные class для проверки класса для соответствующего свойства в классе. Укажите класс после имени свойства. Например, следующее свойство хранит DropDown объект и проверяет его класс.
properties (Access = private, Transient, NonCopyable) DropDown matlab.ui.control.DropDown end
Иногда может потребоваться определить свойство, которое может хранить различные формы и классы значений. Например, если определено свойство, которое может хранить символьный вектор, массив ячеек символьных векторов или строковый массив, опустите проверку размера и класса или используйте пользовательский метод проверки свойств. Дополнительные сведения о проверке свойств см. в разделе Проверка значений свойств.
Одно из преимуществ определения компонента пользовательского интерфейса как подкласса ComponentContainer базовый класс состоит в том, что он также наследует от matlab.mixin.CustomDisplay класс. Это позволяет настроить список свойств MATLAB ®, отображаемых в окне команд при ссылке на компонент пользовательского интерфейса без точки с запятой. Чтобы настроить отображение свойства, перегружайте getPropertyGroups способ. В рамках этого метода можно настроить список свойств и порядок списка. Например, рассмотрим FitPlot , который имеет следующие общие свойства.
properties LineColor {validateattributes(LineColor,{'double'}, ... {'<=',1,'>=',0,'size',[1 3]})} = [1 0 0] XData (1,:) double = NaN YData (1,:) double = NaN end
Следующее getPropertyGroups метод задает список свойств скалярного объекта как XData, YData, и LineColor.
function propgrp = getPropertyGroups(obj) if ~isscalar(obj) % List for array of objects propgrp = getPropertyGroups@matlab.mixin.CustomDisplay(obj); else % List for scalar object propList = {'XData','YData','LineColor'}; propgrp = matlab.mixin.util.PropertyGroup(propList); end end
Когда пользователь ссылается на экземпляр этого компонента пользовательского интерфейса без точки с запятой, MATLAB отображает настроенный список.
p = FitPlot
p =
FitPlot with properties:
XData: NaN
YData: NaN
LineColor: [1 0 0]Дополнительные сведения о настройке отображения свойств см. в разделе Настройка отображения свойств.
update МетодВ большинстве случаев update метод класса реконфигурирует все релевантные аспекты компонента пользовательского интерфейса, зависящие от общедоступных свойств. Иногда реконфигурация включает дорогостоящий расчет, который занимает много времени. Если расчет включает только подмножество свойств, можно создать класс для выполнения этого кода только в случае необходимости.
Один из способов оптимизации update метод заключается в добавлении следующих элементов в класс:
Частная собственность под названием ExpensivePropChanged который принимает logical значение. Это свойство указывает, изменились ли какие-либо свойства, использованные в дорогостоящем расчете.
A set метод для каждого свойства, участвующего в дорогостоящем расчете. Внутри каждого set метод, установите ExpensivePropChanged свойство для true.
Вызываемый защищенный метод doExpensiveCalculation который выполняет дорогостоящий расчет.
Условный оператор в update метод, который проверяет значение ExpensivePropChanged. Если значение равно true, выполнить doExpensiveCalculation.
Следующий код предоставляет шаблон для этой конструкции.
classdef OptimizedUIComponent < matlab.ui.componentcontainer.ComponentContainer properties Prop1 Prop2 end properties(Access=private,Transient,NonCopyable) ExpensivePropChanged (1,1) logical = true end methods(Access = protected) function setup(obj) % Configure UI component % ... end function update( obj ) % Perform expensive computation if needed if obj.ExpensivePropChanged doExpensiveCalculation(obj); obj.ExpensivePropChanged = false; end % Update other aspects of UI component % ... end function doExpensiveCalculation(obj) % Expensive code % ... end end methods function set.Prop2(obj,val) obj.Prop2 = val; obj.ExpensivePropChanged = true; end end end
В этом случае Prop2 участвует в дорогостоящем расчете. set.Prop2 метод устанавливает значение Prop2, а затем он устанавливает ExpensivePropChanged кому true. В следующий раз update метод запускается, он вызывает doExpensiveCalculation только если ExpensivePropChanged является true. Затем, update продолжает обновлять другие аспекты компонента пользовательского интерфейса.
В этом примере определяется FitPlot класс для интерактивного отображения полиномов наилучшего вписывания и использует все четыре из этих передовых практик. Свойства, определенные в блоке свойств, имеют значения по умолчанию и используют проверку размера и класса. getPropertyGroups метод определяет пользовательский порядок отображения свойства. changeFit способ выполняет расчет потенциально дорогостоящей полиномиальной аппроксимации, и update выполняется метод changeFit только в случае изменения выводимых на печать данных.
Чтобы определить этот класс, сохраните FitPlot определение класса в файл с именем FitPlot.m в папке, расположенной по пути MATLAB.
classdef FitPlot < matlab.ui.componentcontainer.ComponentContainer % Choose a fit method for your plotted data properties LineColor {validateattributes(LineColor,{'double'}, ... {'<=',1,'>=',0,'size',[1 3]})} = [1 0 0] XData (1,:) double = NaN YData (1,:) double = NaN end properties (Access = private, Transient, NonCopyable) DropDown matlab.ui.control.DropDown Axes matlab.ui.control.UIAxes GridLayout matlab.ui.container.GridLayout DataLine (1,1) matlab.graphics.chart.primitive.Line FitLine (1,1) matlab.graphics.chart.primitive.Line FitXData (1,:) double FitYData (1,:) double ExpensivePropChanged (1,1) logical = true end methods (Access=protected) function setup(obj) % Set the initial position of this component obj.Position = [100 100 300 300]; % Create the grid layout, drop-down, and axes obj.GridLayout = uigridlayout(obj,[2,1], ... 'RowHeight',{20,'1x'},... 'ColumnWidth',{'1x'}); obj.DropDown = uidropdown(obj.GridLayout, ... 'Items',{'None','Linear','Quadratic','Cubic'}, ... 'ValueChangedFcn',@(s,e) changeFit(obj)); obj.Axes = uiaxes(obj.GridLayout); % Create the line objects obj.DataLine = plot(obj.Axes,NaN,NaN,'o'); hold(obj.Axes,'on'); obj.FitLine = plot(obj.Axes,NaN,NaN); hold(obj.Axes,'off'); end function update(obj) % Update data points obj.DataLine.XData = obj.XData; obj.DataLine.YData = obj.YData; % Do an expensive operation if obj.ExpensivePropChanged obj.changeFit(); obj.ExpensivePropChanged = false; end % Update the fit line obj.FitLine.Color = obj.LineColor; obj.FitLine.XData = obj.FitXData; obj.FitLine.YData = obj.FitYData; end function changeFit(obj) % Calculate the fit line based on the drop-down value if strcmp(obj.DropDown.Value,'None') obj.FitXData = NaN; obj.FitYData = NaN; else switch obj.DropDown.Value case 'Linear' f = polyfit(obj.XData,obj.YData,1); case 'Quadratic' f = polyfit(obj.XData,obj.YData,2); case 'Cubic' f = polyfit(obj.XData,obj.YData,3); end obj.FitXData = linspace(min(obj.XData),max(obj.XData)); obj.FitYData = polyval(f,obj.FitXData); end end function propgrp = getPropertyGroups(obj) if ~isscalar(obj) % List for array of objects propgrp = getPropertyGroups@matlab.mixin.CustomDisplay(obj); else % List for scalar object propList = {'XData','YData','LineColor'}; propgrp = matlab.mixin.util.PropertyGroup(propList); end end end methods function set.XData(obj,val) obj.XData = val; obj.ExpensivePropChanged = true; end function set.YData(obj,val) obj.YData = val; obj.ExpensivePropChanged = true; end end end
Определите некоторые образцы данных и используйте их для создания экземпляра FitPlot.
x = [0 0.3 0.8 1.1 1.6 2.3]; y = [0.6 0.67 1.01 1.35 1.47 1.25]; p = FitPlot('XData',x,'YData',y)
ans =
FitPlot with properties:
XData: [1×43 double]
YData: [1×43 double]
LineColor: [1 0 0]
Используйте раскрывающийся список для отображения квадратичной кривой наилучшего вписывания.

Установите LineColor для изменения цвета кривой наилучшего вписывания на зеленый.
p.LineColor = [0 0.5 0];
