Когда вы разрабатываете пользовательский компонент пользовательского интерфейса как подкласс ComponentContainer
базовый класс, можно использовать определенные методы, чтобы сделать код более устойчивым, эффективным, и удобным для пользователя. Это особое внимание методов о том, как вы задаете и управляете свойствами своего класса. Используйте любого, которые полезны для типа компонента, который вы хотите создать и пользовательский опыт, который вы хотите обеспечить.
Инициализируйте Значения свойств — Набор состояние по умолчанию компонента пользовательского интерфейса в случае, если ваши пользователи вызывают неявного конструктора без любых входных параметров.
Проверка значений свойств — Убедитесь, что значения допустимы перед использованием их.
Настройте Отображение Свойства — Предоставляют индивидуально настраиваемый список свойств в Командном окне когда справочники пользователя объект компонента пользовательского интерфейса без точки с запятой.
Оптимизируйте Метод обновления — Улучшают производительность update
метод, когда только подмножество ваших свойств используются в длительном вычислении.
Для примера этих методов смотрите Пример: Оптимизированная Аппроксимация полиномом Компонент пользовательского интерфейса с Индивидуально настраиваемым Отображением Свойства.
Кроме того, существуют определенные факторы и ограничения, чтобы иметь в виду, хотите ли вы использовать свой пользовательский компонент пользовательского интерфейса в App Designer или совместно использовать ваш компонент с пользователями, которые разрабатывают приложения в App Designer. Эти факторы перечислены на отдельной странице, в Конфигурируют Пользовательские Компоненты пользовательского интерфейса для App Designer.
Присвойте значения по умолчанию для всех публичных свойств вашего класса. Это позволяет MATLAB создавать допустимый компонент пользовательского интерфейса, даже если пользователь не использует некоторые аргументы name-value, когда они вызывают метод конструктора.
Для компонентов пользовательского интерфейса, которые содержат график и имеют свойства, которые хранят координатные данные, установите начальные значения к 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
значение. Это свойство указывает, изменилось ли какое-либо из свойств, используемых в дорогом вычислении.
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];