Когда вы разрабатываете пользовательский компонент как подкласс ComponentContainer
базовый класс, вы можете использовать определенные методы, чтобы сделать ваш код более надежным, эффективным, и удобным для пользователя. Эти методы фокусируются на том, как вы определяете и управляете свойствами своего класса. Используйте все, что полезно для типа компонента, который вы хотите создать, и пользовательского опыта, который вы хотите предоставить.
Initialize Property Values - Установите состояние по умолчанию компонента UI в случае, если ваши пользователи вызывают неявный конструктор без каких-либо входных параметров.
Проверьте значения свойств - убедитесь, что значения действительны перед их использованием.
Настройка отображения свойств - Обеспечивает настраиваемый список свойств в Командном окне, когда пользователь ссылается на объект компонента пользовательского интерфейса без точки с запятой.
Оптимизируйте обновление Метод - Улучшите эффективность update
метод, когда в длительном вычислении используется только подмножество ваших свойств.
Для примера этих методов смотрите Пример: Оптимизированный Аппроксимацией полиномом Компонент пользовательского интерфейса с Настроенным Отображением Свойств.
В сложение существуют определенные факторы и ограничения, чтобы иметь в виду, если вы хотите использовать свой пользовательский компонент в App Designer или поделиться своим компонентом с пользователями, которые разрабатывают приложения в App Designer. Эти факторы перечислены на отдельной странице в разделе Настройка пользовательских компонентов для App Designer.
Назначьте значения по умолчанию для всех общественной собственности вашего класса. Это позволяет MATLAB создать допустимый компонент UI, даже если пользователь опускает некоторые аргументы в виде имя-значение, когда он вызывает метод конструктора.
Для компонентов пользовательского интерфейса, которые содержат график и имеют свойства, которые хранят данные координат, установите начальные значения 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
.
Можно также проверить свойства, которые хранят базовые объекты компонента в компоненте пользовательского интерфейса. Для этого необходимо знать правильное имя класса для каждого объекта. Чтобы определить имя класса объекта, вызовите соответствующую функцию компонента UI в командной строке, а затем вызовите class
функция для получения имени класса. Например, если вы планируете создать раскрывающийся компонент в своем setup
method, вызывать 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
участвует в дорогостоящем расчете. The set.Prop2
метод устанавливает значение Prop2
и затем устанавливает ExpensivePropChanged
на true
. В следующий раз, update
метод запускается, он вызывает doExpensiveCalculation
только если ExpensivePropChanged
является true
. Затем, update
метод продолжает обновлять другие аспекты компонента UI.
Этот пример задает FitPlot
класс для интерактивного отображения полиномов наилучшего полинома и использует все четыре из этих лучших практик. Свойства, заданные в блоке свойств, имеют значения по умолчанию и используют size и валидацию класса. The getPropertyGroups
метод задает пользовательский порядок отображения свойств. The 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];