Component Position Relative to UIFigure
14 views (last 30 days)
Show older comments
Hi Friends,
First time posting, so go easy on me. I've got an App in App Designer with a bunch of nested grid components that I'm trying to place a uiimage over top of. So, I tried making a function that grabs the position of a component relative to the master UIFigure, as opposed to just the parent object.
function pos = getPos(app, component)
% Initialize the position as the component's position relative to its parent
pos = component.Position;
% Traverse up the parent hierarchy until we reach the UIFigure
parent = component.Parent;
while ~isa(parent, 'matlab.ui.Figure')
% If the parent is a GridLayout, adjust the position based on the grid cell
if isa(parent, 'matlab.ui.container.GridLayout')
% Get the grid layout properties
grid = parent;
row = component.Layout.Row;
col = component.Layout.Column;
% Calculate the pixel dimensions of the grid cell
cellPos = app.getGridCellPosition(grid, row, col);
% Adjust the component's position relative to the grid cell
pos(1:2) = pos(1:2) + cellPos(1:2);
else
% For non-grid parents, simply add the parent's position
pos(1:2) = pos(1:2) + parent.Position(1:2);
end
% Move up to the next parent
parent = parent.Parent;
end
end
I've also got functions now for the case of component.Parent being a GridLayout, so app.getGridCellPosition is supposed to get the position of the component's cell, and another to resolve relative sizes and convert them into pixels.
function cellPos = getGridCellPosition(app, grid, row, col)
% Get the grid's position and dimensions
gridPos = grid.Position;
gridWidth = gridPos(3);
gridHeight = gridPos(4);
% Get the row heights and column widths
rowHeights = grid.RowHeight;
colWidths = grid.ColumnWidth;
% Convert relative sizes (e.g., '1x') to absolute pixel values
rowHeights = app.resolveRelativeSizes(rowHeights, gridHeight);
colWidths = app.resolveRelativeSizes(colWidths, gridWidth);
% Calculate the x-position of the cell (left-to-right)
% Sum the widths of all columns to the left of the current column
cellX = sum(colWidths(1:col-1));
% Calculate the y-position of the cell (bottom-to-top)
% Sum the heights of all rows above the current row
cellY = gridHeight - sum(rowHeights(1:row));
% Get the width and height of the cell
cellWidth = colWidths(col);
cellHeight = rowHeights(row);
% Return the cell position [x, y, width, height]
cellPos = [cellX, cellY, cellWidth, cellHeight];
end
function sizes = resolveRelativeSizes(app, relativeSizes, totalSize)
% Convert relative sizes (e.g., '1x') to absolute pixel values
sizes = zeros(1, numel(relativeSizes));
relativeUnits = 0;
fixedUnits = 0;
% First, calculate the total size allocated to fixed units
for i = 1:numel(relativeSizes)
if isnumeric(relativeSizes{i})
fixedUnits = fixedUnits + relativeSizes{i};
elseif ischar(relativeSizes{i}) && endsWith(relativeSizes{i}, 'x')
relativeUnits = relativeUnits + str2double(relativeSizes{i}(1:end-1));
end
end
% Calculate the size per relative unit
sizePerUnit = (totalSize - fixedUnits) / relativeUnits;
% Resolve the sizes
for i = 1:numel(relativeSizes)
if isnumeric(relativeSizes{i})
sizes(i) = relativeSizes{i};
elseif ischar(relativeSizes{i}) && endsWith(relativeSizes{i}, 'x')
sizes(i) = str2double(relativeSizes{i}(1:end-1)) * sizePerUnit;
end
end
end
My issue is its getting this position way wrong - overestimating the height by almost double, and underestimating the width by almost double. Has anyone done this before? Any idea what's wrong with my current implementation?
Answers (1)
Deepak
on 5 Jun 2025
I understand that you are trying to compute the absolute pixel position of a component inside a deeply nested "uigridlayout" in App Designer, to accurately place a "uiimage" over it. You have written a custom function to traverse up the UI hierarchy and compute positions based on grid cell sizes. However, the results are significantly off — which is likely due to manual calculations not accounting for internal spacing, padding, and layout behavior of the grid.
A more reliable and simpler alternative is to use built-in "getpixelposition" function of MATLAB, which handles all the layout math internally. To get the position of any UI component relative to the main "uifigure", you can use:
pos = getpixelposition(component, true);
The second argument (true) ensures the returned position is relative to the figure, not just the immediate parent.
Please find attached the documentation of "getpixelposition" for reference:
getpixelposition: www.mathworks.com/help/matlab/ref/getpixelposition.html
I hope this helps.
0 Comments
See Also
Categories
Find more on Develop uifigure-Based Apps in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!