Component Position Relative to UIFigure
    12 vues (au cours des 30 derniers jours)
  
       Afficher commentaires plus anciens
    
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?
Réponses (1)
  Deepak
 le 5 Juin 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 commentaires
Voir également
Catégories
				En savoir plus sur Develop uifigure-Based Apps dans Help Center et File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


