App Desinger: How to access Labels/Spinners via "Tags" in a custom UI component?

48 views (last 30 days)
I have a modularized App Designer app with several custom UI components. One UI component is a setting for units (e.g. km/h - mph or deg - radiant). These settings should be applied to all other custom UI components. To reduce the implementation work I wan't a generic solution like:
  1. User changed the setting from "rad" toi "deg"
  2. all custom UI components get notified and get the changed data
  3. in the components should be a function with updates all Labels tagged with "LabelUnitAngle" from "rad" to "deg"
The non-generic solution is already working: comp.WheelAngleunitLabel.Text=comp.appSettings.units.angle.text;
comp.WheelAngleSpinner.Value = comp.ParamStore.WheelAngle*comp.appSettings.units.angle.factor;
I tried findall and findobj and tried using metaclasses but still no luck.
  2 Comments
dpb
dpb on 27 Nov 2025 at 15:31
It would undoubtedly help if you could post the startup code section that creates the components in question.
Can you find the app uifigure itself programmatically, first, just for starters?
Have you tried passing the UIFigure handle as the object tree starting point in findall(), etc., ...?
Walter
Walter on 28 Nov 2025 at 6:35
Thanks @dpb that you would like to help me. Without a meta class it was not possible for me. I finally found a solution:
function updateElementsByTags(comp)
%UPDATEELEMENTSBYTAGS Update UI labels in this component based on Tag values.
%
% This method scans all private, transient, non-copyable graphics
% properties of the component and updates their Text property
% depending on the Tag value. The unit strings are taken from
% comp.appSettings.units.*.text.
% Get only the UI handles (graphics objects); we ignore the names here
[~, handles] = getPrivateUiComponents(comp);
for k = 1:numel(handles)
h = handles(k);
% Safety check: only process objects that actually have Tag and Text
if ~isprop(h, "Tag") || ~isprop(h, "Text")
continue;
end
% Use the Tag to decide which unit text to apply
switch string(h.Tag)
case "TagUnitAngle"
h.Text = comp.appSettings.units.angle.text;
case "TagUnitVelocity"
h.Text = comp.appSettings.units.velocity.text;
case "TagUnitYawRate"
h.Text = comp.appSettings.units.yawrate.text;
case "TagUnitLength"
h.Text = comp.appSettings.units.length.text;
case "TagUnitAcceleration"
h.Text = comp.appSettings.units.acceleration.text;
otherwise
% Ignore all other tags
end
end
function [names, handles] = getPrivateUiComponents(obj)
%GETPRIVATEUICOMPONENTS Return private transient graphics properties.
%
% [NAMES, HANDLES] = GETPRIVATEUICOMPONENTS(OBJ) inspects the
% metaclass of OBJ, selects properties that are:
% - private
% - Transient
% - NonCopyable
% - not Constant
% - not Dependent
%
% For each of these properties, the current value is read. If the
% value is a graphics object (or array of graphics objects),
% they are collected into HANDLES. NAMES returns the corresponding
% property names.
% Get metaclass information
mc = metaclass(obj);
plist = mc.PropertyList; % array of matlab.metadata.Property objects
% Select only UI-related properties based on their metadata
isUiProp = arrayfun(@(p) ...
strcmp(p.GetAccess, "private") && ...
p.Transient && ...
p.NonCopyable && ...
~p.Constant && ...
~p.Dependent, ...
plist);
plist = plist(isUiProp);
% Collect names
names = {plist.Name};
% Initialize empty array of graphics handles
handles = gobjects(0);
% Read property values and keep only graphics objects
for k = 1:numel(names)
v = obj.(names{k});
% v may be a scalar handle, an array of handles, or something else
if isgraphics(v)
% Ensure we treat v as a column vector of handles
handles(end+1:end+numel(v)) = v(:); %#ok<AGROW>
end
end
end
end

Sign in to comment.

Answers (1)

Mario Malic
Mario Malic on 29 Nov 2025 at 11:18
Moved: Image Analyst on 29 Nov 2025 at 23:27
Just thinking out here, wouldn't you want an each component to have an internal method that changes values/labels/anything that relates to the selected unit?
Create an event in your main component and make it trigger when the unit is changed (user interaction). Subscribe your other components to it and fire up the internal event to change units.
  4 Comments
Walter
Walter on 1 Dec 2025 at 6:20
I have a listener to appSettingsChanged and an event that changes the units. My question is more for the next step. How to make the event generic? The background is that I want to make an UIcomponent template. The developers should not think about adding code to the event if they add a new spinner+label (they should only tag them).
Mario Malic
Mario Malic on 2 Dec 2025 at 7:41
Edited: Mario Malic on 2 Dec 2025 at 7:42
i see what you mean. i think, that, if you add Tags to the UI component, you would need to give devs a clear instruction how to do it. For example, if you have an Edit Field and Label component that are paired up to display the physical quantity you want to show. Then you would tag them as Quantity_1 and Value_1, then you would do something similar for all components that you want to use to show the values. This is a quick solution, but it works. You can search components within the UIFigure by Tags property to find the components you have given tag to, check findall function.
I don't know how difficult this is since I haven't played with custom components, but, what if you actually add a extend the default UI components to account for units? For example, to add logic for units and values in the combo box that is mentioned above.

Sign in to comment.

Categories

Find more on Create Custom UI Components in Help Center and File Exchange

Products


Release

R2024b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!