Overwriting Grid Layout Does Not Delete Existing Grid Layout.

Overwriting an existing Grid Layout does not delete the existing Grid Layout. I think this might be the cause the random issues I am currently encountering in App Designer. Is this a bug? My real app needs to overwrite grid layouts often.
Please run the attached app as an example.

7 Comments

The orginal code had typo.
The start up function should have the following code.
function startupFcn(app)
for n = 1:20
app.a = uigridlayout(app.UIFigure,[1,n]);
end
app.UIFigure.Children()
end
The startup function is unreliable to do what you're after I think -- instead of hoping you get the right handles (although you may list them, you're not saving that list and so the only one you have access to at this point is the last one). Save the handles when creating them -- but do you really mean to be creating 20 of these puppies of sizes 1:20? I've never used it but reading the doc looks to me like there's only supposed to be one of them of some size that you then use in which to place the other gui components.
function startupFcn(app)
NGrid=20; % I think this must be wrong usage of grid layout component???
hGrid=gobjects(NGrid,1); % Preallocate for the handles
for n = 1:NGrid
hGrid(n)=uigridlayout(app.UIFigure,[1,n]); % I doubt this is really right...still
end
app.hGrid=hGrid; % save in the global struct for use elsewhere
end
That should give you access to the objects but I'm still pretty sure this isn't the right way to do whatever it is you're tying to do...
This is just an example. In reality I have a layout class that controls layouts of my app. It does not matter if I do this in a startup function or a seperate file.
The goal of this sample was to show MATLAB's behavior when a uigridlayout is overwritten.
I found this issue, while I was trying to troubleshoot my earlier question. It could be related.
The problem with your original code is fundamental that you don't have the handles to the objects in question so there's no way you can address the individual ones to overwrite it and see what it does/doesn't do.
Show us the code trying to do whatever it is you're trying to do and that it actually talks to the object in question.
I showed the best example I could provide that shows the issue. It is pretty easy to see. Any more information will require an NDA or to much time to create. Please note I am already working on NDA so I can share my code with MATHWORKS support.
I think you are misunderstanding my question. I am trying to determine if this is a bug?
Nevertheless my actual app has multiple possible layouts. When I want to change my app view, I hide the app components and can call a function that rearranges all the componentss using main and sub gridlayouts. Then I make my components visible again. When the view needs to change the same process repeats again. Thus, I am constatntly creating new grid layouts. Each view creates its own set of grid layouts. Every time my gui switchcs views, MATLAB still retains the main gridlayout from the prevous view. Within an hour my app will be UIfigure with X main grid layouts. I only use / acess one main grildayout at a time.
I define a main gridlayout as a gridlayout that has a UIfigure as its direct parent.
I have a theory that this is causing the error in the link above.
I looked at that code; I didn't see anything in it that does anything with those layouts so it's not possible to see just how you're trying to do this.
I still say if you don't have the handles to these various layouts you can't do anything with any one of them specifically, and I certainly would NOT expect from the documenation that somehow "overwriting" a given grid layout (not even sure how you would be thinking you're "overwriting" it; there's no such functionality documented that would be similar to the behavior of subplot, say, that will transparently delete existing axes if a new one overlays an existing one's position.
If your code is intended to demonstrate changing layout sizes as is, then as I mentioned before, it's not the way to go about rearranging the app layout -- you change the properties/sizes of the layout dynamically by changing its properties instead; there are examples in the doc of creating resizing UIs based on content at runtime.
The gridlayout itself covers the entire uifigure and has components in it; some of which may be nested grids, but NOT multiple gridlayouts that one can swap out; that's not the model.
Without a lot more detail of just how this manipulation is being done, I'd put the crash-and-burn symptoms down as pilot error.
There might could be additional documentation and/or perhaps the use you've made should provide a warning -- there's not enough detail given in the doc to be totally unambiguous about making multiple calls to uigridlayout without a parent argument and not deleting an existing handle first as to what that actually does or if that is or is not an acceptable programming practice.
That could be worth a service request from tech support as to whether that is or is not considered legal. But, certainly it is NOT a documented usage in any of the mutiple examples and looking at the organization of how it is used in those examples, that certainly doesn't appear to me to be the intended use so I'm not surprised if it seems to cause issues when doing so.

Sign in to comment.

Answers (2)

Try calling this little function:
%=====================================================================
% Erases all lines and rectangles from the specified image axes.
function ClearLinesFromAxes(handlesToAxes)
axesHandlesToChildObjects = findobj(handlesToAxes, 'Type', 'line');
if ~isempty(axesHandlesToChildObjects)
delete(axesHandlesToChildObjects);
end
axesHandlesToChildObjects = findobj(handlesToAxes, 'Type', 'rectangle');
if ~isempty(axesHandlesToChildObjects)
delete(axesHandlesToChildObjects);
end
return; % from ClearLinesFromAxes
If you also want to remove lines created by xline() and yline() I believe you have to find objects of those types also.
Well, still without any real klews as to what it is you're trying to do here, I believe that based on my reading of the doc of syntax and examples for the gridlayout object, the way to accomplish what the above code would do for a given layout would be
function startupFcn(app)
NGridColumns=20;
hGrid=uigridlayout(app.UIFigure,[1,1]); % Create the grid, save handle, '1x'by'1x' initially
for n = 2:NGridColumns
hUIG.ColumnWidth=repmat({'1x'},1,n); % reset column to "n" elements
end
app.hGrid=hGrid; % save in the global struct for use elsewhere
end
IOW, change the grid layout you have defined, don't try to overlay multiple layouts on the same figure -- that just isn't the way it works, there's only one layout(*) but it can take on (almost) any desired configuration dynamically.
I'm guessing that probably one of the auto-fit scenarios would more nearly be what you're looking for, where the container will resize automagically based on its input and you're trying to do that with "roll your own" code instead of using builtin features. But, that's a guess since we're pretty-much blind here.
(*) At the top app figure level; there can be nested layouts or layouts inside containers like panels, but they're still then "sub-layouts" of the parent.

Categories

Products

Release

R2022a

Asked:

on 18 Aug 2022

Edited:

dpb
on 19 Aug 2022

Community Treasure Hunt

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

Start Hunting!